2014-05-21 86 views
1

我正在写一个使用棱镜的WPF应用程序,并面临以下困境: 我有一个视图,它公开了2个区域,一个用于网格,另一个用于过滤器面板,使高级过滤网格中的项目。棱镜和视图的多个实例

这些视图是由棱镜发现并实例化到指定区域。 应用过滤器时,必须根据相应的过滤器更新网格。这可以通过例如使用控制器(如果ViewModel驻留在相同模块中)或使用事件(使用EventAggragator)来实现。到现在为止还挺好。

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

这怎么能最好地实现?

+0

您是否检查“RegionContext”属性是否有帮助?它在类似的问题上被证明是有用的。 –

回答

0

你是如何填充这两个区域的?您的“父”视图是否明确地在其上调用regionManager.RequestNavigate(),或者是否在应用程序启动期间使用regionManager.RegisterViewWithRegion()“修复”了区域到其视图?

对于前者,您的父视图可以(比如说)生成一个GUID,并在调用RequestNavigate()时使用上下文参数将其传递给子视图。视图可以在OnNavigatedTo()内抓取这个值。如果使用EventAggregator,则可以将GUID作为消息对象的属性公开,并且在订阅时使用谓词方法重载,因此图视图仅接收包含期望GUID的消息。

如果您使用的是RegisterViewWithRegion,事情会变得更加棘手。我知道你可以在该地区的XAML设置上下文值,所以下面的GUID的想法,并假设VM自曝称为MyViewGuid通过属性生成的GUID值: -

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

我还没有找到一个简单的方法将该上下文值赋予子视图模型(因为在这种情况下他们的INavigationAware方法不会被调用)。我用了一个哈克方法 - 在孩子的意见的构造,设置更改到父区域的背景值的事件处理程序: -

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

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

0

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

一般来说,只要有可能,我宁愿查看与注入相比的废弃物。在大多数情况下,我使用“ExportView”并在代码隐藏中导入ViewModel。

关于导航方法: 使用RequestNavigate()传递上下文似乎有点棘手,因为它需要从不同模块的每个参与视图中调用。这意味着无论何时创建父视图,都应该使用上下文发布事件,以指示每个模块执行相关导航。因为视图不属于同一个区域,所以我不确定“GetObservableContext()”是否可以工作(我无法在我的测试中使它工作)。 另外,我对添加“上下文”概念和关联逻辑到ViewModels有点不情愿。

我当时的想法是通过处理视图中的上下文逻辑:

  1. 实现自定义触发它得到一个PubSubEvent类型和上下文对象并订阅使用上下文作谓语该事件。然后我可以在ViewModel中调用一个comman。它看起来像这样:

    <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来实现。 代码将lokk是这样的:

    <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> 
    

的FilterChanged事件将从视图模型与相关ARGS提高。

棘手的部分是处理参数: 1.从源ViewModel传递参数。 2.使用参数和上下文发布Prism“PubSub”事件。 3.剥离用户端的上下文并使用相关参数触发命令。

任何见解?