Еще одна реализация WPF Event to Command (с проблемами) - PullRequest
2 голосов
/ 21 октября 2011

Я смотрю на различные реализации подключения ICommand к событию элемента управления.Так, например, GotFocus в TextBox должен вызывать 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 ]

1 голос
/ 21 октября 2011

Использование триггеров Blend Event и действия сводит на нет необходимость обрабатывать ваши собственные коллекции.И его можно добавить к любому элементу управления.

См. MVVM Lights EventToCommand

Или мое расширение этого здесь. (источник)

1 голос
/ 21 октября 2011

Есть несколько способов, с помощью которых вы можете подойти к этому, используя Attached Property или наследуя от 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>
0 голосов
/ 21 октября 2011

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