WPF,谁能解释下这个怪异的鼠标事件

dsr5vbtb 2014-04-28 10:41:51

<Window x:Class="WPF4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF4"
Title="MainWindow" Height="550" Width="725">
<Grid Background="Yellow" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Border Name="border1" Background="Red" Height="100" Width="100" MouseLeave="Border_MouseLeave"/>
</Grid>
</Window>


public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
border1.Background = new SolidColorBrush(Colors.Black);
}
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.DragMove(); //移动窗体
}
}


在上面的代码中,Grid的MouseLeftButtonDown事件是移动窗体,Border的MouseLeave事件是将自己的背景色改变成黑色。
现在有这么个看不懂的情况:
当窗体启动后,把鼠标放到Border上方,然后按下鼠标左键,然后松开,此时看到Border的背景色立即变成黑色了。我不明白的就是鼠标并没有移开Border,为什么会引发Border的MouseLeave事件呢?
...全文
360 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
若简LL 2016-03-23
  • 打赏
  • 举报
回复
将grid的mousedown放到border里,因为border接到mousedown冒泡到grid,grid的dragmove将焦点从border移到grid,border就出发了mouseleave
dsr5vbtb 2014-04-30
  • 打赏
  • 举报
回复
还有更确切点的解释吗?
aXen 2014-04-29
  • 打赏
  • 举报
回复
根据事件的定义,事件路由可以按两种方向之一传播,但是通常会在元素树中从源元素向上“冒泡”,直到它到达元素树的根(通常是页面或窗口)。 如果您以前用过 DHTML 对象模型,则可能会熟悉这个冒泡概念。
aXen 2014-04-29
  • 打赏
  • 举报
回复
是因为事件冒泡,也叫事件路由[MSDN: http://msdn.microsoft.com/ZH-CN/library/ms742806(v=VS.110,d=hv.2).aspx]
dianjixue1 2014-04-29
  • 打赏
  • 举报
回复
引用 8 楼 dsr5vbtb 的回复:
[quote=引用 7 楼 dianjixue1 的回复:] 就算把this.DragMove()写在border1的MouseLeftButtonDown事件上,鼠标抬起后一样会触发border1的MouseLeave事件的。 这个方法应该是把焦点脱离程序了
你的意思是DragMove方法,让鼠标离开border了吗[/quote] 也可以这么说,DragMove方法,让鼠标回到最上层的Grid,然后又回到了border。只能这么理解。
dsr5vbtb 2014-04-29
  • 打赏
  • 举报
回复
引用 7 楼 dianjixue1 的回复:
就算把this.DragMove()写在border1的MouseLeftButtonDown事件上,鼠标抬起后一样会触发border1的MouseLeave事件的。 这个方法应该是把焦点脱离程序了
你的意思是DragMove方法,让鼠标离开border了吗
dianjixue1 2014-04-29
  • 打赏
  • 举报
回复
就算把this.DragMove()写在border1的MouseLeftButtonDown事件上,鼠标抬起后一样会触发border1的MouseLeave事件的。 这个方法应该是把焦点脱离程序了
dianjixue1 2014-04-29
  • 打赏
  • 举报
回复
这个事情是这样的,当窗体启动后,把鼠标放到Border上方,然后按下鼠标左键,这个时候触发 Grid_MouseLeftButtonDown事件。为什么明明在Border上方按下左键却触发了Grid的左键事件呢?这就是WPF的事件“冒泡”,就是把事件触发冒到最顶级了。这里就和Winform有很大的不同。 触发了Grid_MouseLeftButtonDown事件后,执行this.DragMove(),关键还是DragMove。 DragMove事件结束后,将依次触发控件的MouseLeave事件至最顶层。然后再触发控件的MouseEnter事件至最顶层 例如楼主的层级 Grid border1 不管DragMove写在哪一层的MouseLeftButtonDown事件上,在最下层的左键按下都会触发,在DragMove执行完成后(鼠标抬起),会执行 border1_MouseLeave——border1_MouseEnter 如果再加一层 Grid border1 border2 在border2上按下鼠标左键,抬起后执行 border2_MouseLeave——border1_MouseLeave——border2_MouseEnter——border1_MouseEnter
dsr5vbtb 2014-04-29
  • 打赏
  • 举报
回复
引用 4 楼 KumaPower 的回复:
你把this.DragMove();注释掉就知道了。
我知道是DragMove方法作的怪,但是是什么原因呢?什么原理呢
dsr5vbtb 2014-04-29
  • 打赏
  • 举报
回复
有没有MSDN官方的解释呢?
Bonjour-你好 2014-04-29
  • 打赏
  • 举报
回复
你把this.DragMove();注释掉就知道了。
dsr5vbtb 2014-04-29
  • 打赏
  • 举报
回复
楼上这位朋友,感谢你的回复,不过,你的回答似乎与我的问题不着边啊
dsr5vbtb 2014-04-29
  • 打赏
  • 举报
回复
有没有MSDN官方的解释呢

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧