EventToCommandを使って、ViewModelへEventArgs渡す


はじめに

MVVMは、ViewとViewModelをバインディングでのみ結合するところに利点があります。
ですが、ButtonのCommandのように、ViewからViewModelへトリガーを渡すようなものも必要です。
Commandは、便利なのですが汎用的に全てのコントロールが対応している訳ではないため使い方が限定されます。
私は、普段WPF開発に慣れもあって、Livetを使っているのですが、マウスホイールのようなイベントをViewModelへ渡すのに、Behaviorを自作するなど工夫が必要でした。
改めて、ネット検索してみたところGalaSoft MvvmLightには、EventToCommand.csというTriggerActionが用意されており、便利そうなので使ってみました。

問題点

WPFのマウスホイールのイベントは、MouseWheelEventArgsクラスのDeltaプロパティの値を見て、回転方向と回転速度を取得します。
EventTriggerとLivetCallMethodActionを組み合わせてもMouseWheelEventArgsは、ViewModelへは渡ってこないため上手く実装できない訳です。

便利なEventToCommandという機能

MvvmLightには、EventToCommandという機能が用意されておりコマンドのパラメーターへイベントパラメーターを載せて呼び出してくれます。
下記のような使い方です。(PassEventArgsToCommand="True"にする必要があります)

Sample.xaml
<Image Source="{Binding Source}" Stretch="Uniform">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="PreviewMouseWheel">
            <ml:EventToCommand Command="{Binding MouseWheelCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
     </i:Interaction.Triggers>
</Image>
Viewmodel.cs
private Livet.Commands.ListenerCommand<System.Windows.RoutedEventArgs> _mouseWheelCommand;

public Livet.Commands.ListenerCommand<System.Windows.RoutedEventArgs> MouseWheelCommand
{
    get
    {
        if (this._mouseWheelCommand == null)
        {
            this._mouseWheelCommand = new Livet.Commands.ListenerCommand<System.Windows.RoutedEventArgs>(this.MouseWheel);
        }
        return this._mouseWheelCommand;
    }
}

private void MouseWheel(RoutedEventArgs args)
{
    var mouseWheelEventArgs = (MouseWheelEventArgs)args;
}

汎用的で応用の効きそうな機能ですよね。
知っていると非常に実装効率が上がりそうな機能なので知ってて損は無いと思います。