MouseBinding the mousewheel to zoom in WPF and MVVM

Kage picture Kage · Feb 16, 2010 · Viewed 11.2k times · Source

OK, I've figured out how to get my Grid of UI elements to zoom, by using LayoutTransform and ScaleTransform. What I don't understand is how I can get my View to respond to CTRL+MouseWheelUp\Down to do it, and how to fit the code into the MVVM pattern.

My first idea was to store the ZoomFactor as a property, and bind to a command to adjust it.

I was looking at something like:

<UserControl.InputBindings>
 <MouseBinding Command="{Binding ZoomGrid}" Gesture="Control+WheelClick"/>
</UserControl.InputBindings>

but I see 2 issues:

1) I don't think there is a way to tell whether the wheel was moved up or down, nor can I see how to determine by how much. I've seen MouseWheelEventArgs.Delta, but have no idea how to get it.

2) Binding to a command on the viewmodel doesn't seem right, as it's strictly a View thing.

Since the zoom is strictly UI View only, I'm thinking that the actual code should go in the code-behind.

How would you guys implement this?

p.s., I'm using .net\wpf 4.0 using Cinch for MVVM.

Answer

Liero picture Liero · Sep 23, 2011

the real anwser is to write your own MouseGesture, which is easy.

<MouseBinding Gesture="{x:Static me:MouseWheelGesture.CtrlDown}"  
              Command="me:MainVM.SendBackwardCommand" />

public class MouseWheelGesture : MouseGesture
{
    public static MouseWheelGesture CtrlDown
        => new MouseWheelGesture(ModifierKeys.Control) { Direction = WheelDirection.Down};

    public MouseWheelGesture(): base(MouseAction.WheelClick)
    {
    }

    public MouseWheelGesture(ModifierKeys modifiers) : base(MouseAction.WheelClick, modifiers)
    {
    }

    public WheelDirection Direction { get; set; }

    public override bool Matches(object targetElement, InputEventArgs inputEventArgs)
    {
        if (!base.Matches(targetElement, inputEventArgs)) return false;
        if (!(inputEventArgs is MouseWheelEventArgs args)) return false;
        switch (Direction)
        {
            case WheelDirection.None:
                return args.Delta == 0;
            case WheelDirection.Up:
               return args.Delta > 0;
            case WheelDirection.Down:
                return args.Delta < 0;
            default:
                return false;
        }
    }

    public enum WheelDirection
    {
      None,
      Up,
      Down,
    }
}