-->

如何绑定RelayCommand(MVVM)到的RoutedCommand? (的Command

2019-10-20 23:09发布

我想创建一个自定义类的CommandBinding,其中执行的RoutedCommand在执行我的视图模型的RelayCommand的。

目前只有创建已在执行的代码隐藏类的方法化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泡沫向下和向上处理?

Answer 1:

我想到了我自己的解决方案。 它不是最漂亮的,但它的工作。

我从ContentControl中的。 新的控制有一个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); }
    }
}


文章来源: How to bind a RelayCommand(MVVM) to a RoutedCommand? (CommandBinding)