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