2014-09-12 106 views
1

我想创建一个CommandBinding的自定义类,其中执行RoutedCommand时执行ViewModel的RelayCommand。如何将RelayCommand(MVVM)绑定到RoutedCommand? (CommandBinding)

当前只有在codebehind类中创建具有Executed方法的CommandBindings的可能性。 实施例:

<CommandBinding Command="ApplicationCommands.Close" Executed="CloseCommandHandler" 
       CanExecute="CanExecuteHandler"/> 

这需要在后面的代码CloseCommandHandler梅索德。

我想写下面的内容。

<CommandBinding RoutedCommand="ApplicationCommands.Close" Command={Binding Path=CloseCommand}/> 

唯一的问题是,我无法找到气泡向下和向上的RoutedCommands的事件。 没有

OnPreviewCommand(object command, object commandParammeter) 
OnCommand(object command, object commandParammeter) 

哪里的RoutedCommand泡沫向下和向上处理?

回答

0

我想出了我自己的解决方案。它不是最美丽的,但它的工作。

我从ContentControl派生而来。新的Control具有RoutedCommandBindings属性,其中包含RoutedCommands和RelayCommands之间的“排序”CommandBindings列表。

它可以像这样使用。

<CSControls:RoutedCommandBinder> 
    <CSControls:RoutedCommandBinder.RoutedCommandBindings> 
     <CSControls:RoutedCommandBindingCollection> 
     <CSControls:RoutedCommandBinding RoutedCommand="{x:Static ApplicationCommands.New}" Command="{Binding Path=AddInstanceCommand}"/> 
     </CSControls:RoutedCommandBindingCollection> 
    </CSControls:RoutedCommandBinder.RoutedCommandBindings> 
    <CSControls:RoutedCommandBinder.Content> 
     <!-- Every RoutedCommand of type ApplicationCommands.New will execute the binded RelayCommand "AddInstanceCommand--> 
    </CSControls:RoutedCommandBinder.Content> 
</CSControls:RoutedCommandBinder> 

这里是CustomControl代码。

public class RoutedCommandBinder : ContentControl 
{ 
    public RoutedCommandBinder() 
    { 
     this.DataContextChanged += RoutedCommandBinder_DataContextChanged; 
    } 

    public static readonly DependencyProperty RoutedCommandBindingsProperty = DependencyProperty.Register("RoutedCommandBindings", typeof(RoutedCommandBindingCollection), typeof(RoutedCommandBinder), new PropertyMetadata(new RoutedCommandBindingCollection(), OnRoutedCommandBindingsChanged)); 
    public RoutedCommandBindingCollection RoutedCommandBindings 
    { 
     get { return (RoutedCommandBindingCollection)this.GetValue(RoutedCommandBindingsProperty); } 
     set { SetValue(RoutedCommandBindingsProperty, value); } 
    } 

    private static void OnRoutedCommandBindingsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     RoutedCommandBinder binder = (RoutedCommandBinder)d; 
     binder.CommandBindings.Clear(); 
     SetDataContextForCommandBindings(binder); 
     if (e.NewValue != null) 
     { 
      RoutedCommandBindingCollection bindings = (RoutedCommandBindingCollection)e.NewValue; 
      foreach (RoutedCommandBinding binding in bindings) 
      { 
       binder.CommandBindings.Add(new CommandBinding(binding.RoutedCommand, binder.RoutedCommandExecuted, binder.CanExecuteRoutedEventHandler)); 
      } 
     } 
    } 

    private void RoutedCommandBinder_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     SetDataContextForCommandBindings(this); 
    } 

    private static void SetDataContextForCommandBindings(RoutedCommandBinder binder) 
    { 
     if (binder.DataContext != null && binder.RoutedCommandBindings != null) 
     { 
      foreach (RoutedCommandBinding binding in binder.RoutedCommandBindings) 
      { 
       binding.DataContext = binder.DataContext; 
      } 
     } 
    } 

    private void RoutedCommandExecuted(object sender, ExecutedRoutedEventArgs e) 
    { 
     RoutedCommandBinding binding = this.RoutedCommandBindings.FirstOrDefault(t => t.RoutedCommand == e.Command); 
     if (binding != null) 
     { 
      binding.Command.Execute(e.Parameter); 
     } 
    } 

    private void CanExecuteRoutedEventHandler(object sender, CanExecuteRoutedEventArgs e) 
    { 
     RoutedCommandBinding binding = this.RoutedCommandBindings.FirstOrDefault(t => t.RoutedCommand == e.Command); 
     if (binding != null) 
     { 
      e.CanExecute = binding.Command.CanExecute(e.Parameter); 
     } 
    } 
} 

public class RoutedCommandBindingCollection : List<RoutedCommandBinding> 
{ 
} 

public class RoutedCommandBinding : FrameworkElement 
{ 
    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(RoutedCommandBinding), new PropertyMetadata(null)); 
    public ICommand Command 
    { 
     get { return (ICommand)this.GetValue(CommandProperty); } 
     set { SetValue(CommandProperty, value); } 
    } 

    public static readonly DependencyProperty RoutedCommandProperty = DependencyProperty.Register("RoutedCommand", typeof(RoutedCommand), typeof(RoutedCommandBinding), new PropertyMetadata(null)); 
    public RoutedCommand RoutedCommand 
    { 
     get { return (RoutedCommand)this.GetValue(RoutedCommandProperty); } 
     set { SetValue(RoutedCommandProperty, value); } 
    } 
}