2012-02-03 17 views
4

DelegateCommandやRelayCommandなどの基本的なICommandインターフェイスの実装には、RoutedCommandクラスに含まれるInputGesturesプロパティがありません。このプロパティはKeyGestureへのバインディングをサポートし、RoutedUICommandのTextプロパティはコントロールのヘッダーの設定をサポートします。例:RoutedUICommandとViewModelのICommandとInputBindingの使用

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

ファイルメニュー項目の下に「Open Ctrl + O」と表示されます。ジェスチャーの場合、InputBindingsは入力ゲストをコマンドにマッピングしますが、InputGestureTextサポートを失います。

KeyGesturesを定義するときに、ビューモデルのICommandにバインディングを簡単に保つ方法& XAMLまたはビューモデル内のコマンドのテキスト?たとえば、Contextメニューとメインメニューに表示されているコマンドで、RoutedUICommandがサポートしているのと同じHeader & InputGestureTextを表示したいのですが、コマンドの実装はWindowのコードの背後ではなく、ビューモデル内にあります。

+0

私はこの問題に遭遇しましたが、それは重要ではありませんでした。私は、ICommandとジェスチャーをリンクする、何らかの種類の添付プロパティの使用を考えました。この問題についての進捗状況を教えてください。 –

答えて

4

リフレクタでMenuItemを見ると、私たちはの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が検索されます。これは、MenuItemのこの機能を利用するために、コマンドがRoutedCommand/のインスタンスでなければならないことを示しています。それは方法が仮想ではありませんCanExecute/ExecuteだからリフレクタでRoutedCommandを見ると

は、RoutedCommandから派生DelegateCommandを作成する簡単な方法は、ありません。

私たちのようなものコーディングできます

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方法を防ぐことはできません。どちらが問題になるかもしれない。

また、DelegateCommand(または他の場所)を検索してテキスト/ジェスチャを使用するのに十分なスマートなカスタムMenuItemを作成することもできます。

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

} 
関連する問題