鼠标事件
鼠标键盘如何触发路由事件
自定义的路由事件可以简单的分为两类:
- 在依赖属性的PropertyChangedCallback中被调用,当属性值被更改后,发布属性变化路由事件。依赖属性可以响应鼠标键盘被修改,从而发布自定义路由事件。
- Mouse.MouseLeftButtonDown附件事件,可以被任何继承自UIElement的元素自动发布,我们可以在宿主类的构造函数中订阅鼠标键盘事件,事件处理程序调用自定义路由事件。
鼠标输入
MouseEnter和MouseLeave
当鼠标进入和离开元素时,发布事件。二者是直接路由事件,这是合理的,根据逻辑树的嵌入规则,进入内层元素前肯定先进入外围元素,所以无需冒泡和隧道,让事件从内部向外传播。
MouseMove和PreviewMouseMove
鼠标在元素上移动时,会发布此事件。
MouseEventArgs
<Button x:Name="btn" Height="50" Width="100" MouseMove="Button_MouseMove"></Button>
private void Button_MouseMove(object sender, MouseEventArgs e)
{
Point point = e.GetPosition(btn);
this.Title = point.X.ToString() + point.Y.ToString();
}
MouseEventArgs的成员方法GetPosition(IInputElement relativeTo)能够获取鼠标相对指定元素的坐标,参考原点是元素的左上角。
IsMouseOver和IsMouseDirectlyOver
UIElement有两个依赖属性IsMouseOver和IsMouseDirectlyOver。IsMouseOver检测鼠标是否在元素及其子元素上面,IsMouseDirectlyOver检测鼠标是否在元素上面而非其子元素上面。
这两个属性最常用的地方就是触发器,当鼠标操作元素时用来改变元素的样式和外观。
鼠标单击
MouseLeftButtonDown,PreviewMouseLeftButtonDown,MouseLeftButtonUp,PreviewMouseLeftButtonUp
MouseRightButtonDown,PreviewMouseRightButtonDown,MouseRightButtonUp,PreviewMouseRightButtonUp
这些事件定义在UIElement中,Control类又添加了MouseDoubleClick和PreviewMouseDoubleClick,Button添加了Click。
事件的参数是MouseButtonEventArgs,它继承自MouseEventArgs,它的ClickCount属性可用来判断双击还是单击。
高级元素新增的鼠标事件可能覆盖掉UIElement中的鼠标事件,在使用时尝试一下选择合适的事件就可以了。
鼠标拖拽
鼠标捕获
鼠标拖放
- 拖放源在MouseLeftButtonDown事件处理程序中调用DragDrop.DoDragDrop( )选择复制的内容。
- 拖放目标的AllowDrop=True,才能接受拖动的内容。
- 可以在拖放目标的DragEnter事件处理程序中通过e.GetDataPresent()添加接受或拒绝拖放内容的逻辑。不可接受时,鼠标呈中间带红线的圆形。
- 当鼠标在拖放目标松开左键后,拖放目标的Drop事件处理程序接受拖放内容。
拖拽文件显示路径
<Grid>
<TextBlock Background="Orange" Height="50" Width="270" Drop="TextBlock_Drop" AllowDrop="True"/>
</Grid>
private void TextBlock_Drop(object sender, DragEventArgs e)
{
(sender as TextBlock).Text = ((System.Array)e.Data.GetData(System.Windows.DataFormats.FileDrop)).GetValue(0).ToString();
}
<StackPanel>
<TextBlock Background="Orange" Height="50" Width="270" Margin="0,50,0,0" MouseLeftButtonDown="TextBlock_MouseLeftButtonDown" Text="待拖拽"/>
<TextBlock Background="Lime" Height="50" Width="270" Drop="TextBlock_Drop" AllowDrop="True" Margin="0,50,0,0" DragDrop.DragEnter="TextBlock_DragEnter" DragDrop.Drop="TextBlock_Drop"/>
</StackPanel>
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragDrop.DoDragDrop((sender as TextBlock), (sender as TextBlock).Text, DragDropEffects.Copy);
}
private void TextBlock_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.Text))
{
e.Effects = DragDropEffects.Copy;
}
else
{
e.Effects = DragDropEffects.None;
}
}
private void TextBlock_Drop(object sender, DragEventArgs e)
{
(sender as TextBlock).Text = e.Data.GetData(DataFormats.Text) as string;
}