【问题标题】:Is it a good practice to have prism's RegionManager reference in viewmodel在 viewmodel 中有 prism 的 RegionManager 参考是一个好习惯吗
【发布时间】:2017-02-23 15:07:32
【问题描述】:

我正在使用 PRISM 开发复合 WPF 应用程序。我有一个具有父用户控件的窗口。此父用户控件定义了许多子区域。子视图使用 MEF 的“REGIONEXPORT”属性导出自己。每个子视图导入/创建自己的视图模型。父用户控件具有“确定”和“取消”按钮。按“确定”后,我想验证并保存所有子视图模型。如果任何验证失败,则需要知道父用户控件的视图模型。为此,我使用复合命令并将其设置在 RegionContext 中。每个子视图模型都通过区域上下文获取该复合命令,希望您了解基本上我需要在父视图模型和子视图模型之间共享数据。所以我需要在子视图模型中获取 RegionContext,因为我正在导入视图模型构造函数中的 RegionManager(使用导入构造函数)从 RegionManager 我得到区域上下文,然后是命令。

public class FooViewModel
{
     [ImportingConstructor]
     public FooViewModel(IRegionManager regionManager)
     {
        var regionContext = regionManager.RegionContext;
     }
}
  1. 在视图模型中设置区域管理器是一种很好的做法吗?
  2. 这不会破坏 MVVM 吗?我们在视图模型中有视图相关的东西
  3. 有没有更好的方法在视图模型之间共享数据(事件聚合器除外)

【问题讨论】:

    标签: wpf mvvm prism prism-5


    【解决方案1】:

    通过视图模型的构造函数获取对区域管理器的引用并不罕见。这是获得它的首选方法。当我需要使用区域管理器进行导航时,我总是这样做。

    这种方法不会破坏 MVVM。虽然,我不确定你打算用RegionContext 本身做什么。

    另一种将数据从一个虚拟机传递到另一个虚拟机的方法是通过NavigationParameters 和区域管理器RequestNavigate 函数。下面是一个例子。

    private readonly IRegionManager _regionManager;
    
    public YourViewModel(IRegionManager regionManager)
    {
        _regionManager = regionManager;
    }
    
    Private void DoNavigation()
    {
        var parameters = new NavigationParameters();
        parameters.Add("Key", <a value or an object to pass>);
        _regionManager.RequestNavigate(“ContentRegion”, “YourViewName”, parameters);
    }
    

    您可以在接收 VM 的 OnNavigatedTo 方法中检查参数集合中的值。

    public override void OnNavigatedTo(NavigationContext navigationContext)
    {
        var paramKey = navigationContext.Parameters.Where(item => item.Key == "Key").FirstOrDefault();
    
        if (paramKey.Value != null)
        {
            // Do something…
        }    
    }
    

    您需要实现INavigationAware 才能使OnNavigatedTo 工作。

    编辑:

    如果您希望数据共享比通过区域上下文与另一个视图模型对话更松散耦合,并且您不想使用事件聚合器,那么共享服务可能是另一种方式。

    使用共享服务,部分或全部视图模型可以引用它,并且当服务中的属性更改时,任何引用它的对象都可以执行。此共享服务可以实现 Prism 附带的BindableBase,因此在发生更改时会通知。使用您使用的任何容器注册共享服务,在视图模型的ctor 中获取它,并根据需要引用属性。

    Shared Service Example

    【讨论】:

    • 谢谢理查德。 :) 但我仍然很困惑。这个 RegionManager 包含区域和视图,并在 viewmodel 中访问 regionmanager(查看相关的东西),我觉得它与 MVVM 相矛盾。
    • 没有人强迫您以视图为先进行导航,尽管ViewModelLocator 使其简洁明了。您还可以先导航视图模型,然后区域包含您的视图模型。
    • 嗨@Haukinger,我的要求中没有导航。我有一个父视图和子视图,两个视图都没有任何直接参考。父视图创建它的虚拟机,子视图创建它的虚拟机。现在我需要在父子虚拟机之间共享数据。为此,我正在使用 RegionContext。
    • @Sivasubramanian 您对事件聚合器有疑问吗?如果您不喜欢使用 RegionContext 方法,为什么不使用它?
    • @Sivasubramanian,在这种情况下,只需让两个视图模型都可以访问一个服务,为它们提供数据。
    猜你喜欢
    • 2016-01-03
    • 2012-08-14
    • 2014-12-22
    • 2020-08-25
    • 2015-05-08
    • 2010-09-11
    • 1970-01-01
    • 2019-07-17
    • 1970-01-01
    相关资源
    最近更新 更多