2011-05-13 65 views
4

我有一個上下文菜單內的下列菜單項在我的WPF應用程序:如何在頂級WPF MenuItem被禁用時禁用它?

<MenuItem Header="Email"> 
     <MenuItem Command="Commands:CommandRepository.GenerateUserEmailCommand" 
       CommandParameter="{Binding Path=SelectedItems}" 
       Header="Email User"> 
     </MenuItem> 
     <MenuItem Command="Commands:CommandRepository.GenerateManagerEmailCommand" 
        CommandParameter="{Binding Path=SelectedItems}" 
        Header="Email Manager"> 
     </MenuItem> 
</MenuItem> 

的問題是,當兩個電子郵件命令的返回CanExecute =假的,因此這兩個命令得到禁止,頂級MenuItem「電子郵件」保持啓用狀態。我知道我可能會將頂級菜單項的IsEnabled綁定到它的Children屬性,然後使用轉換器來決定何時應禁用它,但似乎應該會自動發生。這不是使用CommandBindings(即他們照顧IsEnabled)的全部要點嗎?有什麼更好的方法來完成這個?

回答

1

爲什麼你的「Email」MenuItem被禁用?只是因爲孩子們?

我認爲你的方法使用多重綁定和轉換器是一個很好的方式來做你想做的事情。

1

我能想到的兩種方法可以做到這一點:

1)如果你不介意的話後面的代碼(我嘗試用WPF避免它),你可以只創建IsEnabledChanged的事件處理程序,如果是檢查IsEnabled屬性設置爲false。如果是,那麼你可以做這樣的事情

ParentMenuItem.IsEnabled = ParentMenuItem.Items.Count(c => c is MenuItem && (c as MenuItem).IsEnabled == true) > 0 

2)父菜單項和子菜單項類型創建一個視圖模型,並結合已啓用父菜單項查看到視圖模型的IsEnabled屬性。視圖模型會使用類似的

this.Children.Count(c => c.IsEnabled == true) > 0 
1

定義RootMenu命令,然後將其添加到根菜單

Header="Email" Command="Commands:CommandRepository.RootMenu" CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=.}" 

綁定命令如下RootMenuCanExecute

public static void DropDownMenuCanExecute(object sender, CanExecuteRoutedEventArgs e) { 
     e.CanExecute = false; 
     ItemsControl parent = e.Parameter as ItemsControl; 
     if (parent.Items.Count == 0) { return; } 
     foreach (var i in parent.Items) { 
      ICommandSource cs = i as ICommandSource; if (cs==null) { continue; } 
      if (cs.Command == null) { continue; } 
      if (cs.Command.CanExecute(cs.CommandParameter)) { e.CanExecute = true; return; } 
     } 
    } 

它返回false有點cpu昂貴,但它的工作。 Whatch out沒有太多的MenuItem兒童