为什么 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>

好吧,我想你把MouseDown事件误认为是财产。没有IsMouseDown属性,但存在类似的IsPressed属性,但仅适用于继承ButtonBase的类。如果要保持代码隐藏干净,则应只在代码隐藏中使用 event 或编写附加属性。

这就是你的做法。创建类:

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 = sender as UIElement;
            if (element != null)
            {
                SetIsMouseDown(element, true);
            }
        }
        private static void element_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            var element = sender as UIElement;
            if (element != null)
            {
                SetIsMouseLeftButtonDown(element, true);
            }
        }
        private static void element_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
        {
            var element = sender 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 = sender 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"

您可以在Style.Triggers中使用 MouseDown 事件,但您必须为此使用 EventTrigger。

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

请记住

引发事件的条件后,操作将不会撤消 不再是真的。

使用 Control.Triggers 时,可以使用 PreviewMouseLeftButtonDown,将控件替换为正在使用模板的控件项:

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

相关内容

  • 没有找到相关文章

最新更新