Another implementation of WPF Event to Command (with problems)

风流意气都作罢 提交于 2019-12-01 11:28:36

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>

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)

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"
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!