2012-02-03 48 views
4

基本ICommand接口實現(如DelegateCommand和RelayCommand)缺少RoutedCommand類中包含的InputGestures屬性。此屬性支持綁定到KeyGesture,並且RoutedUICommand中的Text屬性支持設置控件的標題。例如:RoutedUICommand與ICommand在ViewModel中使用InputBinding

<MenuItem Header="File"> 
    <MenuItem Command="Open" /> 

結果是菜單項標記爲:「打開Ctrl + O」在文件菜單項下。對於手勢,InputBindings會將輸入的guesture映射到該命令,但是會丟失InputGestureText支持。

在定義KeyGestures時如何保持綁定到視圖模型的ICommands的簡單性& XAML或視圖模型中的命令的文本?例如,我想在上下文菜單和主菜單中顯示一條命令,以顯示與RoutedUICommand支持的相同的Header & InputGestureText,但該命令的實現位於視圖模型內部,而不在Window的代碼背後。

+0

我遇到過這個問題,但並不重要。我想過使用某種附加的屬性用法,將ICommand和手勢聯繫起來。請讓我知道你在這個問題上的進展。 – 2012-02-03 16:27:03

回答

4

尋找在反射器MenuItem,我們可以看到菜單項如何拿起Header/InputGesture值,這是:

private static object CoerceInputGestureText(DependencyObject d, object value) 
{ 
    RoutedCommand command; 
    MenuItem item = (MenuItem) d; 
    if ((string.IsNullOrEmpty((string) value) && 
     !item.HasNonDefaultValue(InputGestureTextProperty)) && 
     ((command = item.Command as RoutedCommand) != null)) 
    { 
     InputGestureCollection inputGestures = command.InputGestures; 
     // Get appropriate gesture.... 
    } 
    return value; 
} 

有類似的代碼,來強迫基於所述電流指令Header屬性,但在這種情況下,它尋找RoutedUICommand。這告訴我們,這些命令必須是RoutedCommand/RoutedUICommand的一個實例,以利用MenuItem的這一功能。

綜觀反射RoutedCommand,沒有創造一個DelegateCommandRoutedCommand得出一個簡單的方法,因爲它是CanExecute/Execute方法不是虛擬的。

我們可以編寫類似:

public class DelegateCommand : RoutedCommand, ICommand 
{ 
    bool ICommand.CanExecute(object parameter) { 
     // Insert delegate can execute logic 
    } 
    void ICommand.Execute(object parameter) { 
     // Insert delegate execute logic 
    } 
} 

但是,這並不妨礙在RoutedCommand非顯式CanExecute/Execute方法被調用。這可能是也可能不是問題。

或者,我們可以創建一個自定義MenuItem,它足夠聰明,可以查找我們的DelegateCommand(或其他地方)並使用它的文本/手勢。

public class MyMenuItem : MenuItem { 

    static MyMenuItem() { 
     InputGestureTextProperty.OverrideMetadata(typeof(MyMenuItem), 
      new FrameworkPropertyMetadata(string.Empty, null, CoerceInputGestureText)); 
    } 

    private static object CoerceInputGestureText(DependencyObject d, object value) { 
     MenuItem item = (MenuItem)d; 
     var command = item as DelegateCommand; 
     if ((string.IsNullOrEmpty((string)value) && 
      DependencyPropertyHelper.GetValueSource(item, InputGestureTextProperty).BaseValueSource == BaseValueSource.Default && 
      command != null) { 
      InputGestureCollection inputGestures = command.InputGestures; 
      // Get appropriate gesture.... 
     } 

     // Call MenuItem Coerce 
     var coerce = InputGestureTextProperty.GetMetadata(typeof(MenuItem)).CoerceValueCallback; 
     return coerce(d, value); 
    } 

} 
相關問題