为啥 IsMouseOver 被识别而 MouseDown 不是(Wpf 样式触发器)?
Posted
技术标签:
【中文标题】为啥 IsMouseOver 被识别而 MouseDown 不是(Wpf 样式触发器)?【英文标题】:Why IsMouseOver is recognized and MouseDown isn't (Wpf Style trigger)?为什么 IsMouseOver 被识别而 MouseDown 不是(Wpf 样式触发器)? 【发布时间】:2012-05-26 21:48:07 【问题描述】:为什么 IsMouseOver 被识别为 WPF 样式触发器而 MouseDown 不是 - 假设两者都是有效的 UIElement 属性,如 seen here-。第一个触发器运行良好,但第二个触发器甚至无法编译。
<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
并未在您提供的链接中列为属性。 OnMouseDown()
被列为响应事件而调用的方法,而不是属性。
【参考方案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 = 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"
【讨论】:
你能举个例子说明你所说的“写一个附加的属性”吗? 非常感谢这堂课。我不得不使用 PreviewMouseDown 和 PreviewMouseUp 事件来让它工作,但在那之后它很棒。IsPressed
是完全正确的方法,如果你正在设计一个按钮。
@mrpyo 我正在使用您的解决方案(是的,即使在今天 :D )但它不起作用,没有错误,但什么也没做。我在一个滑块的拇指矩形上使用它。我错过了什么?
@agiro 您是否尝试过像 Robert Gowland 推荐的那样使用 PreviewMouseDown 和 PreviewMouseUp(我编辑了答案)?另请记住,如果您有硬编码值,则触发器将不起作用:social.msdn.microsoft.com/Forums/vstudio/en-US/…【参考方案2】:
您可以在Style.Triggers
中使用MouseDown Event,但您必须为此使用EventTrigger。
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</EventTrigger>
记住这一点
一旦条件引发事件,该操作将不会被撤消 不再是真的。
【讨论】:
【参考方案3】:您可以在使用 Control.Triggers 时使用 PreviewMouseLeftButtonDown,将控件替换为正在使用模板的控件项:
<Grid>
<Grid.Triggers>
<EventTrigger RoutedEvent="Grid.PreviewMouseLeftButtonDown">
<BeginStoryboard>
<Storyboard>
...
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
【讨论】:
以上是关于为啥 IsMouseOver 被识别而 MouseDown 不是(Wpf 样式触发器)?的主要内容,如果未能解决你的问题,请参考以下文章
从一个网页复制的东西 粘贴单另一个网页为啥粘贴不全 例如:Reacts with: Rat Predicted: Human, Mouse
第一次提问:为啥'py'被识别但'python'不被识别?在终端中运行的快捷方式? 'echo %PATH%' 给出巨大的路径?