棱镜和视图的多个实例

时间:2014-05-21 17:51:31

标签: wpf mvvm prism

我正在使用Prism编写WPF应用程序并面临以下困境: 我有一个显示2个区域的视图,一个用于网格,另一个用于过滤器面板,它可以对网格中的项目进行高级过滤。

这些观点是由棱镜发现并实例化到指定区域的。 应用过滤器时,必须根据适当​​的过滤器更新网格。例如,这可以通过使用Controller(如果ViewModel驻留在同一模块中)或使用事件(使用EventAggragator)来实现。到目前为止一切都很好。

我的问题是这个视图可能在不同的窗口中有多个实例。因此,我需要知道过滤器的上下文,以便能够确定哪个网格必须受到影响。但是,ViewModel实例彼此不知道。

如何才能最好地实现这一目标?

2 个答案:

答案 0 :(得分:0)

你是如何填充这两个地区的?你的父母"查看显式调用regionManager.RequestNavigate(),或者你"修复"在应用程序启动期间使用regionManager.RegisterViewWithRegion()

查看区域

使用前者,您的父视图可以(比方说)生成GUID,并在调用RequestNavigate()时使用context参数将其传递给子视图。视图可以在OnNavigatedTo()中获取此值。如果您正在使用EventAggregator,则可以将GUID公开为消息对象上的属性,并在订阅时使用谓词方法重载,因此图形视图仅接收包含预期GUID的消息。

如果您使用的是RegisterViewWithRegion,事情会变得更加棘手。我知道您可以在区域的XAML中设置上下文值,因此遵循GUID的想法,并假设VM通过名为MyViewGuid的属性公开生成的GUID值: -

<ContentControl Regions:RegionManager.RegionName="Foo"
                Regions:RegionManager.RegionContext="{Binding MyViewGuid}"/>

我还没有找到一种简单的方法来获取子视图模型的上下文值(假设他们的INavigationAware方法在这种情况下不会被调用)。我使用了一种hacky方法 - 在孩子的观点中&#39;构造函数,设置事件处理程序以更改父区域的上下文值: -

var regionContext = RegionContext.GetObservableContext(this);
regionContext.PropertyChanged += RegionContextOnPropertyChanged;

事件处理程序将是这样的,在我的头顶: -

private void RegionContextOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
    var observableObject = sender as ObservableObject<object>;
    if (observableObject != null && observableObject.Value != null)
    {
         // Get the GUID value from the context and pass to the VM
         // (assuming the VM has a method called SetGuid().
         var myGuid = (Guid)observableObject.Value;
         (DataContext as MyViewModel).SetGuid(myGuid);
    }
}

希望我建议的东西可能有用......!

答案 1 :(得分:0)

感谢您的详细解答! 我已经考虑了建议的解决方案,但仍然不确定最佳方法。

一般来说,只要有可能,我更喜欢观看视频丢弃而不是注射。在大多数情况下,我使用&#34; ExportView&#34;并在代码隐藏中导入ViewModel。

关于导航方法: 使用RequestNavigate()传递Context似乎有点棘手,因为需要从不同的模块为每个参与视图调用它。这意味着无论何时创建父视图,都应使用Context发布事件,以通知每个模块执行相关导航。

关于RegisterViewWithRegion: 由于这些观点不属于同一地区,因此我不确定&#34; GetObservableContext()&#34;会工作(我无法让它在我的测试中工作)。 另外,我对添加&#34; Context&#34;有点不情愿。 ViewModels的概念和相关逻辑。

我在想的是通过以下方式处理视图中的Context逻辑:

  1. 实现获取PubSubEvent类型和Context对象的自定义Trigger,并使用上下文作为谓词来订阅该事件。然后我可以在ViewModel中调用一个commans。它看起来像:

    <i:Interaction.Triggers>
        <Core:PubSubEventTrigger EventType="{x:Type Interfaces:FilterApplied}" 
                                 Context="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}">
            <Core:InvokeCommandActionEx Command="{Binding FilterCommand}"/>
        </Core:PubSubEventTrigger>
    </i:Interaction.Triggers>
    
  2. 使用公共上下文从发布者的视图发布PubSub事件。这可以使用EventTrigger和将发布事件的自定义Action来实现。 代码会像这样:

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="FilterChanged" SourceObject="{Binding}">
            <Core:PubSubPublishEventAction EventType="{x:Type Interfaces:FilterApplied}" Context="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    
  3. FilterChanged事件将从具有相关参数的ViewModel中引发。

    棘手的部分是处理参数: 1.从源ViewModel传递参数。 2.发布Prism&#34; PubSub&#34;具有参数和上下文的事件。 3.在订阅服务器端剥离上下文并使用相关参数触发命令。

    任何见解?