Почему IsMouseOver распознается и MouseDown не является (триггер стиля Wpf)?

Почему IsMouseOver распознается как триггер стиля WPF, а MouseDown не указано, что оба свойства являются действительными свойствами UIElement как здесь.. Первый триггер работает хорошо, а второй даже не компилируется.

<Style.Triggers>
    <Trigger Property="IsMouseOver" Value="true">
        <Setter Property="OpacityMask">
            <Setter.Value>
                <LinearGradientBrush >
                    <GradientStop Color="Transparent" Offset="0"/>
                    <GradientStop Color="Black" Offset="0.5"/>
                    <GradientStop Color="Transparent" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Trigger>
    <Trigger Property="MouseDown" Value="true">
        <Setter Property="OpacityMask">
            <Setter.Value>
                <LinearGradientBrush>
                    <GradientStop Color="Black" Offset="0" />
                    <GradientStop Color="White" Offset="1" />
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Trigger>
</Style.Triggers>

Ответ 1

Ну, я думаю, вы ошибаетесь в событии MouseDown для свойства. Нет свойства IsMouseDown, но существует аналогичное свойство IsPressed, но только для классов, наследующих ButtonBase. Вы должны просто использовать событие в кодировке или написать прикрепленное свойство, если хотите сохранить чистый код.

Вот как вы это делаете. Создать класс:

using System;
using System.Windows;

namespace Mrpyo
{
    public static class MouseDownHelper 
    {
        public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached("IsEnabled", 
        typeof(bool), typeof(MouseDownHelper), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(OnNotifyPropertyChanged)));

        public static void SetIsEnabled(UIElement element, bool value)
        {
            element.SetValue(IsEnabledProperty, value);
        }

        public static bool GetIsEnabled(UIElement element)
        {
            return (bool)element.GetValue(IsEnabledProperty);
        }

        private static void OnNotifyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var element = d as UIElement;
            if (element != null && e.NewValue != null)
            {
                if ((bool)e.NewValue)
                {
                    Register(element);
                }
                else
                {
                    UnRegister(element);
                }
            } 
        }

        private static void Register(UIElement element)
        {
            element.PreviewMouseDown += element_MouseDown;
            element.PreviewMouseLeftButtonDown += element_MouseLeftButtonDown;
            element.MouseLeave += element_MouseLeave;
            element.PreviewMouseUp += element_MouseUp;
        }

        private static void UnRegister(UIElement element)
        {
            element.PreviewMouseDown -= element_MouseDown;
            element.PreviewMouseLeftButtonDown -= element_MouseLeftButtonDown;
            element.MouseLeave -= element_MouseLeave;
            element.PreviewMouseUp -= element_MouseUp;
        }

        private static void element_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var element = e.Source as UIElement;
            if (element != null)
            {
                SetIsMouseDown(element, true);
            }
        }

        private static void element_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var element = e.Source as UIElement;
            if (element != null)
            {
                SetIsMouseLeftButtonDown(element, true);
            }
        }

        private static void element_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var element = e.Source as UIElement;
            if (element != null)
            {
                SetIsMouseDown(element, false);
                SetIsMouseLeftButtonDown(element, false);
            }
        }

        private static void element_MouseUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var element = e.Source as UIElement;
            if (element != null)
            {
                SetIsMouseDown(element, false);
                SetIsMouseLeftButtonDown(element, false);
            }
        }

        internal static readonly DependencyPropertyKey IsMouseDownPropertyKey = DependencyProperty.RegisterAttachedReadOnly("IsMouseDown",
        typeof(bool), typeof(MouseDownHelper), new FrameworkPropertyMetadata(false));
        public static readonly DependencyProperty IsMouseDownProperty = IsMouseDownPropertyKey.DependencyProperty;

        internal static void SetIsMouseDown(UIElement element, bool value)
        {
            element.SetValue(IsMouseDownPropertyKey, value);
        }

        public static bool GetIsMouseDown(UIElement element)
        {
            return (bool)element.GetValue(IsMouseDownProperty);
        }

        internal static readonly DependencyPropertyKey IsMouseLeftButtonDownPropertyKey = DependencyProperty.RegisterAttachedReadOnly("IsMouseLeftButtonDown",
        typeof(bool), typeof(MouseDownHelper), new FrameworkPropertyMetadata(false));
        public static readonly DependencyProperty IsMouseLeftButtonDownProperty = IsMouseLeftButtonDownPropertyKey.DependencyProperty;

        internal static void SetIsMouseLeftButtonDown(UIElement element, bool value)
        {
            element.SetValue(IsMouseLeftButtonDownPropertyKey, value);
        }

        public static bool GetIsMouseLeftButtonDown(UIElement element)
        {
            return (bool)element.GetValue(IsMouseLeftButtonDownProperty);
        }
    }
}

Затем в вашем стиле:

<Setter Property="local:MouseDownHelper.IsEnabled" Value="True"/>
<Style.Triggers>
    <Trigger Property="local:MouseDownHelper.IsMouseLeftButtonDown" Value="True">
        <!-- ... -->
    </Trigger>
</Style.Triggers>

И, конечно, добавьте пространство имен в ваш файл XAML (посмотрите вверху):

xmlns:local="clr-namespace:Mrpyo"

Ответ 2

Вы можете использовать Событие MouseDown в Style.Triggers, но вы должны использовать EventTrigger.

<EventTrigger RoutedEvent="MouseEnter">
    <BeginStoryboard>
        <Storyboard>
            ...
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>

И помните, что

действие не будет отменено после условия, которое вызвало событие больше не верна.

Ответ 3

Вы можете использовать PreviewMouseLeftButtonDown при использовании Control.Triggers, заменяя элемент управления элементом управления, в котором используется шаблон:

 
<Grid>
  <Grid.Triggers>
    <EventTrigger RoutedEvent="Grid.PreviewMouseLeftButtonDown">
      <BeginStoryboard>
        <Storyboard>
          ...
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Grid.Triggers>
</Grid>