c# - Prism MVVM - 将 subview 添加到父 View 而不使用区域和注入(inject),只需 XAML

标签 c# silverlight mvvm controls prism

我对 Silverlight 和 MVVM/Prism 模式相当陌生,所以这可能是一个愚蠢的问题。

我有一个 View ,其中包含自定义控件。这些自定义控件实际上也是 View ,并且有 ViewModel 来驱动它们。

目前要将这些“子” View 添加到我正在使用的 View 中(见图 1),然后在 ViewModel 中我有一个 Initialise() 方法来解析 subview 并注入(inject)它(见图 2)。

图1

<UserControl
x:Class="ProjectA.Module.Screens.Views.PlatformScreenView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Regions="clr-namespace:Microsoft.Practices.Composite.Presentation.Regions;assembly=Microsoft.Practices.Composite.Presentation"
>
<Grid x:Name="LayoutRoot">
    <ContentControl
        Regions:RegionManager.RegionName="FeaturesSelectionControl"
        />
</Grid>

图2
public void Initialise()
{
    IRegion featuresRegion = _regionManager.Regions["FeaturesSelectionControl"];
    featuresRegion.Add(_container.Resolve<IFeatureSelectionControlViewModel>().View);
}

我的问题是我是否必须为要添加的每个控件执行此操作?我理解为什么它会这样工作,但它似乎有很多代码,而且我需要跟踪所有区域名称并确保我没有任何冲突等。有没有更简单的方法可以在没有区域和只是在 XAML 中?

我在 StackOverflow 上看到了 XAML 的片段 here但不确定它是如何工作的,如果它是我想要的 -
<ContentControl Content="{Binding SmartFormViewModel}"/>

任何帮助深表感谢。

詹姆士

最佳答案

澄清后编辑:

看来您根本不想使用 RegionManager,这很好。那么我的建议是这样的:

为您的模块创建一个接口(interface),用于注册 View 创建方法:

public interface IViewRegistry
{
     void RegisterMainView(Func<object> ViewCreationDelegate);
}

您的模块将像这样使用它:
public MyModule : IModule
{
     IViewRegistry _registry;
     public MyModule(IViewRegistry registry)
     {
          _registry = registry;
     }

     public void Initialize()
     {
          _registry.RegisterMainView(() =>
          {
               var vm = new MyViewModel();
               var view = new MyView();
               var view.DataContext = vm;
               return view;
          });
     }
}

然后在你的shell中,你首先实现 View 注册表(这是一个简化......你可能想要更健壮的东西)
public ViewRegistry : IViewRegistry
{
     public static List<Func<object>> ViewFactories
     {
           get { return _viewFactories; }
     }
     static List<Func<object>> _viewFactories = new List<Func<object>>();
     public void RegisterMainView(Func<object> viewFactory)
     {
          _viewFactories.Add(viewFactory);
     }
}

最后,这是你的 shell 如何显示这些东西的。这是它的 ViewModel 首先:
public ShellViewModel : ViewModel
{
     public ObservableCollection<object> MainViews
     {
          ...
     }

     public ShellViewModel()
     {
          MainViews = new ObservableCollection<object>(ViewRegistry.Select(factory => factory()));
     }
}

这是您的 View (看,没有 RegionManager!):
<UserControl ...>
   <Grid>
     <ItemsControl ItemsSource="{Binding MainViews}" />
   </Grid>
</UserControl>

区域经理试图给你我在这里写的所有东西,加上很多可扩展点,但如果你不喜欢 RegionManager 或者你发现它由于某种原因不符合你的需要,这就是你会的方式在没有它的情况下在 Silverlight 中执行此操作。

进一步编辑:

在 OP 发表了更多评论后,我想我明白 OP 只是想在另一个 View 中显示一个 View ,而不必使用 RegionManager。看来 OP 正在使用 RegionManager 在屏幕上显示每个 View ,这可能是矫枉过正。

给我的场景包括地址 View 和从不同父控件使用的关联 ViewModel。这就是我所做的(无论是对还是错):
<UserControl x:Class="Views.MyParentView" ...>
<StackPanel>
     <TextBlock>Blah blah blah some other stuff... blah blah</TextBlock>
     <myViews:AddressView DataContext="{Binding AddressVM}" />
</StackPanel>
</UserControl>

这是父 View 的 View 模型:
public ParentViewModel : ViewModel
{
     public AddressViewModel AddressVM
     {
          ...
     }

     public ParentViewModel()
     {
          AddressVM = new AddressViewModel();
     }
}

就是这样。这可以防止您为了显示这些 View 而费尽心思。

RegionManager 非常适合将父容器 View 与 subview 分离,但如果它们都位于同一个地方(相同的模块/程序集),则没有理由使用 RegionManager 来显示这些 View 。

关于c# - Prism MVVM - 将 subview 添加到父 View 而不使用区域和注入(inject),只需 XAML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2019825/

相关文章:

c# - 部分信任 : How to instantiate a generic type without a generic type argument

silverlight - 从 Silverlight 4(测试版)流式传输网络摄像头

c# - Prism 5.0 在 ViewModel 中包装模型属性

android - MVVM:复杂 View / View 模型-> 多个 LiveData 对象?

c# - 在我的项目 Xamarin 中实现 INotifyPropertyChanged

c# - WCF Rest WebFaultException 总是返回 202

c# - 将 System.Drawing.Common.Bitmap (.NET Standard 2.0) 传递给需要 System.Drawing.Bitmap (.NET 4.7.2) 的类

c# - 具有多列的Android Listview

c# - 如何在 Gridview 页脚中添加 2 行

c# - Windows Phone 8.1后台任务无法注册后台任务