如何将RelayCommand(MVVM)绑定到RoutedCommand? (CommandBinding) [英] How to bind a RelayCommand(MVVM) to a RoutedCommand? (CommandBinding)

查看:112
本文介绍了如何将RelayCommand(MVVM)绑定到RoutedCommand? (CommandBinding)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个CommandBinding的自定义类,其中在执行RoutedCommand时执行ViewModel的RelayCommand.

I want to create a custom class of a CommandBinding, where a RelayCommand of my ViewModel is executed when the RoutedCommand is executed.

当前,只有一种可能性可以创建在Codebehind类中具有Executed方法的CommandBindings. 示例:

Currently there is only the possibility to create CommandBindings which have Executed methods in the codebehind class. Example:

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

这需要后面代码中的CloseCommandHandler方法.

This needs the CloseCommandHandler methode in the code behind.

我想写以下内容.

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

唯一的问题是我找不到RoutedCommands的气泡下降和上升事件. 没有

The only problem is that i can't find the bubble down and up event of the RoutedCommands. There is no

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

在哪里处理了RoutedCommand气泡?

Where is the RoutedCommand bubble down and up handled?

推荐答案

我想出了自己的解决方案.它不是最美丽的,但可以正常工作.

I came up with a solutions of my own. Its not the most beautiful, but its working.

我来自ContentControl.新控件具有RoutedCommandBindings属性,该属性包含RoutedCommands和RelayCommands之间的各种" CommandBindings列表.

I derived from the ContentControl. The new Control has a RoutedCommandBindings property, which contains a list of "sort of" CommandBindings between RoutedCommands and RelayCommands.

可以这样使用.

<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代码.

Here is the CustomControl code.

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

这篇关于如何将RelayCommand(MVVM)绑定到RoutedCommand? (CommandBinding)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆