Home > Software engineering >  How to bind a value to the "Gesture" property of the MouseBinding class? – WPF XAML
How to bind a value to the "Gesture" property of the MouseBinding class? – WPF XAML

Time:09-19

I am currently trying to add the following line of code to my XAML file:

<MouseBinding Command="helix:ViewportCommands.Rotate" Gesture="{Binding ViewportRotateGesture}" />

The problem is that this doesn't work. Whenever I try to bind a string to the "Gesture" property, I get the following exception:

System.Windows.Markup.XamlParseException: 'A 'Binding' cannot be set on the 'Gesture' property of type 'MouseBinding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.'

Using the "MouseAction" property instead of the "Gesture" property does work, however this doesn’t allow you to add any modifiers. Does anybody know how to bind a mouse gesture in combination with a modifier (for example Shift LeftClick)?

CodePudding user response:

This is not a DependencyProperty, but a normal CLR property. You can't bind him. See public virtual InputGesture Gesture.

You can create a Behavior or an Attached Property for this purpose.

Example:

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

namespace Core2022.SO.Chris.AttachedProperties
{
    public static class InputBinding
    {
        /// <summary>Returns the value of the attached property Gesture for the <paramref name="inputBinding"/>.</summary>
        /// <param name="inputBinding"><see cref="System.Windows.Input.InputBinding"/>  whose property value will be returned.</param>
        /// <returns>Property value <see cref="InputGesture"/>.</returns>
        public static InputGesture GetGesture(System.Windows.Input.InputBinding inputBinding)
        {
            return (InputGesture)inputBinding.GetValue(GestureProperty);
        }

        /// <summary>Sets the value of the Gesture attached property to <paramref name="inputBinding"/>.</summary>
        /// <param name="inputBinding"><see cref="System.Windows.Input.InputBinding"/> whose property is setting to a value..</param>
        /// <param name="value"><see cref="InputGesture"/> value for property.</param>
        public static void SetGesture(System.Windows.Input.InputBinding inputBinding, InputGesture value)
        {
            inputBinding.SetValue(GestureProperty, value);
        }

        /// <summary><see cref="DependencyProperty"/> for methods <see cref="GetGesture(System.Windows.Input.InputBinding)"/>
        /// and <see cref="SetGesture(System.Windows.Input.InputBinding, InputGesture)"/>.</summary>
        public static readonly DependencyProperty GestureProperty =
            DependencyProperty.RegisterAttached(
                nameof(GetGesture).Substring(3),
                typeof(InputGesture),
                typeof(InputBinding),
                new PropertyMetadata(null, OnGestureChanged));

        private static void OnGestureChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is not System.Windows.Input.InputBinding inputBinding)
                throw new NotImplementedException($"Implemented only for the \"{typeof(System.Windows.Input.InputBinding).FullName}\" class");

            inputBinding.Gesture = (InputGesture)e.NewValue;
        }
    }
}
<MouseBinding Command="helix:ViewportCommands.Rotate"
              ap:InputBinding.Gesture="{Binding ViewportRotateGesture}"/>
  • Related