【问题标题】:Prism MVVM - Add child View to parent View without using Regions and Injection, just XAMLPrism MVVM - 将子视图添加到父视图而不使用区域和注入,只需 XAML
【发布时间】:2010-01-07 11:19:09
【问题描述】:

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

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

目前要将这些“子”视图添加到我正在使用的视图中(参见图 1),然后在 ViewModel 中我有一个 Initialise() 方法来解析子视图并注入它(参见图 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 here 上看到了 XAML 的 sn-p,但不确定它是如何工作的,以及它是否是我想要的 -

<ContentControl Content="{Binding SmartFormViewModel}"/>

非常感谢任何帮助。

詹姆斯

【问题讨论】:

  • 在您澄清后,我编辑了我的回复。希望这能满足您的需求。
  • 在您发表其他评论后,我进一步编辑了我的回复。我没有意识到您的问题是父视图和子视图的范围稍小。

标签: c# silverlight mvvm controls prism


【解决方案1】:

澄清后编辑:

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

为您的模块创建一个接口,用于注册视图创建方法:

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 中,您首先实现视图注册表(这是一种简化...您可能想要更健壮的东西)

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()));
     }
}

这是你的视图(看,没有 RegionManager!):

<UserControl ...>
   <Grid>
     <ItemsControl ItemsSource="{Binding MainViews}" />
   </Grid>
</UserControl>

区域管理器试图为您提供我在此处编写的所有内容,以及许多可扩展性点,但如果您不喜欢 RegionManager 或者您发现它由于某种原因不符合您的需求,这是如果没有它,您将如何在 Silverlight 中执行此操作。


进一步修改:

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

给我的场景包括一个地址视图和关联的视图模型,该视图模型从不同的父控件中使用。这就是我所做的(无论对错):

<UserControl x:Class="Views.MyParentView" ...>
<StackPanel>
     <TextBlock>Blah blah blah some other stuff... blah blah</TextBlock>
     <myViews:AddressView DataContext="{Binding AddressVM}" />
</StackPanel>
</UserControl>

这是父视图的 viewModel:

public ParentViewModel : ViewModel
{
     public AddressViewModel AddressVM
     {
          ...
     }

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

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

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

【讨论】:

  • 我不认为特定类型的 DataTemplate 在 Silverlight 中的工作?但是我还没有检查过 Sliverlight 4.0。还没有。
  • 废话,你抓住了我。我没有注意到 Silverlight 这个词以某种方式贴满了你的帖子。我的错。然后,您可能会想要使用演示者...您在帖子中提出的方法 仅适用于 DataTemplating,这就是我在回答中采用该方向的原因。我会考虑一下并重新发布。
  • 嗨安德森,感谢您的回复,但我不认为这是我所追求的。也许我的问题还不够清楚,我最终的目标是不必使用区域。用名称定义区域似乎需要付出很多努力,确保该名称不会与现有名称冲突,然后编写一些 C# 将视图插入该区域。我来自 ASP.NET 背景,如果我想将用户控件放在页面上,我只需将其添加到 ASP.NET 标记中。这在 SL 和 MVVM 中可行吗?我希望这是有道理的,并再次感谢您的帮助。
  • 您当然不必使用区域。您可以只拥有一组可用的视图并将您的主视图绑定到该集合。那是你要的吗?我会发布一个例子。我不明白你不想使用 RegionManager。
  • 是的,我认为这就是我想要的。也许一个例子可以帮助我进一步阐明我想要实现的目标——比如我有一个非常简单的“邮政地址”用户控件(由模型、视图模型和视图组成),我在各种 Silverlight 屏幕上使用它。每次我想使用这个控件时,我是否必须在 XAML 中定义一个区域,然后用 C# 中的 RegionManager 注入它?这是在 MVVM 中添加用户控件的推荐方式吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多