2011-10-20 55 views
0

在我們的應用程序中,我們有一箇中心資源,我們爲項目定義所有系統範圍的菜單。這些菜單項已經綁定到系統範圍內爲我們的對象定義的命令。例如,在我們正在處理'Foo'對象的應用程序中的任何地方,我們只需附加'FooContextMenu'資源。很棒。如何在外部定義的上下文菜單中綁定子菜單的複選標記?

但是...其中一個菜單定義了代表枚舉值的子菜單,因此我們希望根據對象的枚舉類型屬性的值檢查相應的菜單項。例如,無處不在顯示一個「富」對象中的UI,我們要顯示該上下文菜單...

FooContextMenu 
    |__First Foo command 
    |__Set Foo Encoding 
    | |__EnumValueA 
    | |__EnumValueB 
    | |__EnumValueC // <-- Show checkbox if 'Foo.SomeEnumProp' == 'C' 
    | |__EnumValueD 
    |__Other Foo command 
    |__Last Foo command 

現在再次,由於命令和上下文菜單資源集中定義的,它們都工作執行代碼就好了。我們無法弄清楚的是如何在全球範圍內處理該複選框。雖然我們可以在任何地方添加「ContextMenuOpening」代碼,但這是問題所在。我們必須在每個地方都加上這個,但我無法想象這就是你必須這樣做的方式。

我確定我錯過了一些盲目顯而易見的事情,考慮到這是基本的Windows應用程序(實際上是任何操作系統)的行爲,但我無法看到它。 (我想知道是否上下文菜單選擇了他們所附的項目的數據上下文,我可以做簡單的綁定,但這只是一個猜測。)想法?

回答

1

關於DataContextContextMenu的行爲有點不同。

<ContextMenu> 
     <MenuItem Header="Foo" 
       Command="{Binding FooCommand}" 
       CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ContextMenu}, Path=PlacementTarget.SelectedItems}"/> 
</ContextMenu> 

MenuItemContextMenu內的DataContext將是父,這是在ViewModel其中最有可能暴露其中ListBox.ItemsSource被綁定到在上面的示例集合。

如果您想直接使用項目列表中顯示的模型,則需要使用CommandParamter方案中上面所示給定項目的相對路徑。如果你想簡單地將常用命令暴露給你的ViewModel,那麼你可以像使用那樣使用綁定,因爲DataContext將是代表項目列表的ViewModel。

針對您的示例,如果您在ViewModel中保留常見行爲,則可能會看起來像這樣。

<ContextMenu> 
     <MenuItem Header="Foo"> 
      <CheckBox 
       Visibility="{Binding Path=YourProperty, 
       Converter={StaticResource BooleanToVisibilityConverter}}"> 
       My CheckBox 
      </CheckBox> 
     </MenuItem> 
</ContextMenu> 

然後,您可以在ViewModel中調用您的屬性,將其調整爲集中所有內容的服務。如果您需要模型在轉換器內做出決定,則需要使用相對路徑來獲取SelectedItem作爲參數。

+0

不確定你的意思是'表現有點不同'。上下文菜單及其關聯的菜單項是否只是選取了將上下文菜單附加到的任何DataContext? (在你的情況下,它看起來像你將它附加到控件上,但我們將它附加到DataTemplate,所以我相信我們已經有了該項目的ViewModel,不需要RelativeSource。)但是,我再也看不出與其他行爲有什麼不同規則綁定(除非你說它是'不同的',因爲它沒有選擇你點擊的* item *的DataContext,這又是有道理的,因爲它沒有附在那裏。) – MarqueIV

+0

@MarqueIV是的,我是指向選定項目的ContextMenu及其關聯的DataContext不是所選項目本身。這是父視圖模型,這對我來說沒有意義。如果你不需要選擇的項目,那麼上面提到綁定到你的ViewModel是微不足道的。 –

+0

但是我做*需要選擇的項目,這是您右鍵單擊的項目。 (*我們在PreviewMouseDown事件中有代碼自動選擇您右鍵單擊的項目,使其成爲選定的項目。)另外,通過將它附加到DataTemplate,您不僅可以獲取所選項目的DataContext,還可以如果您在列表中單擊但不在列表項目中(例如,當項目下面的區域沒有足夠的高度填充時),則不會顯示上下文菜單。 – MarqueIV

相關問題