2014-05-21 112 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.剝離用戶端的上下文並使用相關參數觸發命令。

任何見解?