WPF Event to Command的另一个实现(有问题)

时间:2011-10-21 13:59:08

标签: wpf events xaml icommand

我正在研究将ICommand挂钩到控件事件的各种实现。因此,例如TextBox的GotFocus应该在我的View Model中调用GotFocusCommand。然后我有了一个想法来实现我自己的版本(为了我自己的学习)并且它运行良好,但我只能将一个事件链接到XAML中的一个命令。

(基本上我只是使用反射来查找指定的事件,然后执行一个执行命令的AddEventHandler)

这很好用:

<Button 
  local:EventToCommand.Event="Click" 
  local:EventToCommand.Command="{Binding TestCommand}" 
  />  

但这不是:

<Button 
  local:EventToCommand.Event="Click" 
  local:EventToCommand.Command="{Binding ClickCommand}" 
  local:EventToCommand.Event="GotFocus" 
  local:EventToCommand.Command="{Binding GotFocusCommand}"
  />  

因为它会导致重复的属性名称错误。

是否可以做类似的事情:

<Button>
  <Some Xaml Element>
    <local:EventToCommand Event="Click" Command="{Binding ClickCommand}" />
    <local:EventToCommand Event="GotFocus" Command="{Binding GotFocusCommand}" />
  </Some Xaml Element>
</Button>

将多个事件“映射”到命令?

3 个答案:

答案 0 :(得分:1)

有两种方法可以解决这个问题,要么使用附加属性,要么继承自Button并添加自己的DependencyProperty,其中包含EventToCommand对象列表,当您添加到该集合时,您将事件连接到命令。如果这看起来令人困惑,我可以试着提出一些例子。

C#

    public class EventedButton : Button
{
    public static DependencyProperty EventCommandsProperty
        = DependencyProperty.Register("EventCommands", typeof(EventToCommandCollection), typeof(EventedButton), new PropertyMetadata(null));


    public EventToCommandCollection EventCommands
    {
        get
        {
            return this.GetValue(EventCommandsProperty) as EventToCommandCollection;
        }
        set
        {
            this.SetValue(EventCommandsProperty, value);
        }
    }

    public EventedButton()
    {
        this.EventCommands = new EventToCommandCollection(this);
    }
}

的Xaml:

    <local:EventedButton>
        <local:EventedButton.EventCommands>
            <local:EventToCommand />
        </local:EventedButton.EventCommands>
    </local:EventedButton>

在EventToCommandCollection内部,您可以在将项目添加到集合时附加/分离到您想要的事件。

更新:附加财产

以下是一些将集合作为附加属性的代码:

C#

        public static DependencyProperty CommandsProperty =
        DependencyProperty.RegisterAttached(
        "Commands",
        typeof(ICollection<EventToCommand>),
        typeof(DependencyObject),
        new PropertyMetadata(null, OnCommandsChanged));


    private static void OnCommandsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        // Attach/Detach event handlers
    }

    public static void SetCommands(DependencyObject element, ICollection<EventToCommand> value)
    {
        element.SetValue(CommandsProperty, value);
    }

    public static ICollection<EventToCommand> GetCommands(DependencyObject element)
    {
        return (ICollection<EventToCommand>)element.GetValue(CommandsProperty);
    }

的Xaml:

    <local:EventedButton>
        <local:EventToCommand.Commands>
            <local:EventToCommandCollection>
                <local:EventToCommand/>
            </local:EventToCommandCollection>
        </local:EventToCommand.Commands>
    </local:EventedButton>

答案 1 :(得分:1)

使用混合事件触发器和操作无需处理您自己的集合。 它可以添加到任何控件中。

请参阅MVVM Lights EventToCommand

或我的扩展程序here. (source)

答案 2 :(得分:0)

GalaSoft MVVM Light ToolKit - EventToCommand你可以这样做

<Button> 
  <i:Interaction.Triggers>
     <i:EventTrigger EventName="Click" >
      <cmd:EventToCommand 
          PassEventArgsToCommand="True"
           Command="{Binding ButtonClick}"
       />
    </i:EventTrigger>
 </i:Interaction.Triggers>
  <i:Interaction.Triggers>
     <i:EventTrigger EventName="GotFocus" >
      <cmd:EventToCommand 
          PassEventArgsToCommand="True"
           Command="{Binding ButtonGotFocus}"
       />
    </i:EventTrigger>
 </i:Interaction.Triggers>
</Button>

导入此命名空间的位置

 i- xmlns:i="clr-namespace:System.Windows.Interactivity;
    assembly=System.Windows.Interactivity"
 cmd-xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;
     assembly=GalaSoft.MvvmLight.Extras.WPF4"