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

发布于 2024-12-10 23:13:49 字数 968 浏览 1 评论 0原文

我正在研究将 ICommand 挂接到控件事件的各种实现。因此,例如,文本框的 GotFocus 应该在我的视图模型中调用 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>

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

I am looking at various implementations of hooking a ICommand up to a control's event. So for instance the GotFocus of a TextBox should call a GotFocusCommand in my View Model. I then got an idea to implement my own version (for my own learning) and it is working well, but I can only link one event to one command in the XAML.

( Basically I just use reflection to find the specified Event and then do a AddEventHandler that executes the command )

This works fine :

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

But this does not :

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

as you it leads to a duplicate attribute name error.

Would it be possible to do something like :

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

to "map" multiple events to commands ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浴红衣 2024-12-17 23:13:49

有多种方法可以解决此问题,可以使用附加属性,也可以从 Button 继承并添加您自己的包含 EventToCommand 对象列表的 DependencyProperty,然后在添加到该集合时将事件连接到命令。如果这看起来令人困惑,我可以尝试举一些例子。

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>

There are a couple of ways you could approach this, either using an Attached Property or inheriting from Button and adding your own DependencyProperty that contains a list of EventToCommand objects, and when you add to that collection you wire up the event to command. If this seems confusing, I can try to whip up some examples.

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>

Inside of EventToCommandCollection, you would attach/detach to the Event you wanted when items are added to the collection.

UPDATE: Attached Property

Here is some code to do the collection as an attached property:

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>
你对谁都笑 2024-12-17 23:13:49

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

请参阅 MVVM Lights EventToCommand

或我的扩展 这里。(来源)

Using the Blend Event Triggers and an action negates the need to handle your own collections.
And it can be added to any control.

See MVVM Lights EventToCommand

Or my extension of it here.(source)

来日方长 2024-12-17 23:13:49

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"

GalaSoft MVVM Light ToolKit - EventToCommand you can do this

<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>

Where import this namespaces

 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"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文