WPF没有“IsMouseLeftButtonDown”属性,但您可以创建自己的附加属性来执行此操作,然后对其进行触发。这比向单个控件添加mouseLeftButtonDown事件处理程序要干净得多。
这样做:
-
为ismouseLeftButtonDown(以及其他按钮)创建继承的附加属性
-
创建“已启用”的附加属性以自动设置所需的事件处理程序。
-
直接在控件或任何包含控件上设置“已启用”属性。
-
在触发器或多触发器中使用“IsMouseLeftButtonDown”属性
以下是它的外观:
<Window ...
local:MouseExtensions.Enabled="true" /> <!-- Set the handlers -->
...
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" >
<Setter Property="Cursor" Value="openHand.cur"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="local:MouseExtensions.IsMouseLeftButtonDown" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Cursor" Value="closedHand.cur" />
</MultiTrigger>
</ControlTemplate.Triggers>
下面是如何实现附加属性:
public class MouseExtensions : DependencyObject
{
// IsMouseLeftButtonDown
public static bool GetIsMouseLeftButtonDown(DependencyObject obj) { return (bool)obj.GetValue(IsMouseLeftButtonDownProperty); }
public static void SetIsMouseLeftButtonDown(DependencyObject obj, bool value) { obj.SetValue(IsMouseLeftButtonDownProperty, value); }
public static readonly DependencyProperty IsMouseLeftButtonDownProperty = DependencyProperty.RegisterAttached("IsMouseLeftButtonDown", typeof(bool), typeof(MouseExtensions), new FrameworkPropertyMetadata
{
Inherits=true,
});
// IsMouseMiddleButtonDown
public static bool GetIsMouseMiddleButtonDown(DependencyObject obj) { return (bool)obj.GetValue(IsMouseMiddleButtonDownProperty); }
public static void SetIsMouseMiddleButtonDown(DependencyObject obj, bool value) { obj.SetValue(IsMouseMiddleButtonDownProperty, value); }
public static readonly DependencyProperty IsMouseMiddleButtonDownProperty = DependencyProperty.RegisterAttached("IsMouseMiddleButtonDown", typeof(bool), typeof(MouseExtensions), new FrameworkPropertyMetadata
{
Inherits=true,
});
// IsMouseRightButtonDown
public static bool GetIsMouseRightButtonDown(DependencyObject obj) { return (bool)obj.GetValue(IsMouseRightButtonDownProperty); }
public static void SetIsMouseRightButtonDown(DependencyObject obj, bool value) { obj.SetValue(IsMouseRightButtonDownProperty, value); }
public static readonly DependencyProperty IsMouseRightButtonDownProperty = DependencyProperty.RegisterAttached("IsMouseRightButtonDown", typeof(bool), typeof(MouseExtensions), new FrameworkPropertyMetadata
{
Inherits=true,
});
// Enabled
public static bool GetEnabled(DependencyObject obj) { return (bool)obj.GetValue(EnabledProperty); }
public static void SetEnabled(DependencyObject obj, bool value) { obj.SetValue(EnabledProperty, value); }
public static readonly DependencyProperty EnabledProperty = DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(MouseExtensions), new PropertyMetadata
{
PropertyChangedCallback = (obj, e) =>
{
var element = (FrameworkElement)obj;
if((bool)e.OldValue)
{
element.PreviewMouseDown -= Update;
element.PreviewMouseUp -= Update;
element.MouseEnter -= Update;
element.MouseLeave -= Update;
}
if((bool)e.NewValue)
{
element.PreviewMouseDown += Update;
element.PreviewMouseUp += Update;
element.MouseEnter += Update;
element.MouseLeave += Update;
}
}
});
private static void Update(object sender, MouseEventArgs e)
{
var element = (FrameworkElement)sender;
bool inside = e.RoutedEvent!=Mouse.MouseLeaveEvent;
SetIsMouseLeftButtonDown(element, inside && e.LeftButton==MouseButtonState.Pressed);
SetIsMouseMiddleButtonDown(element, inside && e.MiddleButton==MouseButtonState.Pressed);
SetIsMouseRightButtonDown(element, inside && e.RightButton==MouseButtonState.Pressed);
}
}
工作原理:“已启用”propertychangedcallback将“update”方法添加为四个鼠标事件的处理程序。当其中一个事件发生时,将检查当前鼠标按钮状态,并在“已启用”设置为true的元素上更新is_uuu ButtonDown属性。从那里,这些属性通过逻辑树和可视化树继承下来。但是,如果收到mouseleave,则所有这些属性都设置为false,因为在鼠标再次位于“启用”的元素上之前,不会再次收到任何鼠标事件。