Avec Expression Blend SDK (package NuGet)

L’avantage est que l’on pourra ajouter des properties et comportements personnalisés. On pourrait par exemple ajouter une property pour un Converter de parameter.

using System.Windows;
using System.Windows.Input;
using System.Windows.Interactivity;

namespace WpfEventToCommandBehaviorTest.Behaviors
{
    public class EventToCommand : TriggerAction<DependencyObject>
    {
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommand), new PropertyMetadata(null));

        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.Register("CommandParameter", typeof(object), typeof(EventToCommand), new PropertyMetadata(null));

        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        public object CommandParameter
        {
            get { return (object)GetValue(CommandParameterProperty); }
            set { SetValue(CommandParameterProperty, value); }
        }

        protected override void Invoke(object parameter)
        {
            if (Command != null)
            {
                if (Command.CanExecute(CommandParameter))
                {
                    Command.Execute(CommandParameter);
                }
            }
        }
    }
}

Utilisation:
Exemple on bind l’event « SelectionChanged » d’une ListView sur une commande du ViewModel

Ajout du namespace : xmlns:i= »http://schemas.microsoft.com/expression/2010/interactivity »

Passage de l’élément sélectionné de la liste en parameter (pas besoin de binder un « selected item » du view model à la liste)

<ListView x:Name="MyListView" ItemsSource="{Binding Users}">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged">
            <behaviors:EventToCommand Command="{Binding MyCommand}" CommandParameter="{Binding ElementName=MyListView,Path=SelectedItem}"></behaviors:EventToCommand>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListView>

On peut alors « typer » la commande

public class MyViewModel
{
    public ObservableCollection<User> Users { get; set; }

    public ICommand MyCommand { get; set; }

    public MyViewModel()
    {
        MyCommand = new RelayCommand<User>((user) =>
        {
            // ...
        });
    }
}

Autre possibilités :

  • Utiliser InvokeCommandAction (Sdk Blend)
  • Créer un behavior (Sdk Blend) si on sait exactement quel contrôle et event sont ciblés
  • Utiliser des attached properties (pas besoin du Sdk Blend) mais c’est moins « propre »

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *