【WPF】简单问题,大家帮我看一下。为什么Bubbling时为什么捕捉不到?

nanhe0065 2010-06-09 08:13:42
Grid里有个Button,Button里有个TextBox,鼠标左键点击TextBox时,grid_PreviewMouseLeftButtonDown,btn_PreviewMouseLeftButtonDown,txt_PreviewMouseLeftButtonDown依次被调用,但为什么txt_MouseLeftButtonDown,btn_MouseLeftButtonDown,grid_MouseLeftButtonDown代码不执行呢?

<Grid Name="grid" PreviewMouseLeftButtonDown="grid_PreviewMouseLeftButtonDown" MouseLeftButtonDown="grid_MouseLeftButtonDown" ButtonBase.Click="grid_Click">
<Button Name="btn" PreviewMouseLeftButtonDown="btn_PreviewMouseLeftButtonDown" MouseLeftButtonDown="btn_MouseLeftButtonDown" Click="btn_Click">
<TextBox Name="txt" PreviewMouseLeftButtonDown="txt_PreviewMouseLeftButtonDown" MouseLeftButtonDown="txt_MouseLeftButtonDown" Width="100" />
</Button>
</Grid>


private void btn_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("btn_PreviewMouseLeftButtonDown");
}

private void btn_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("btn_MouseLeftButtonDown");
}

private void txt_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("txt_PreviewMouseLeftButtonDown");
}

private void txt_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("txt_MouseLeftButtonDown");
}

private void grid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("grid_PreviewMouseLeftButtonDown");
}

private void grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine("grid_MouseLeftButtonDown");
}

private void btn_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("btn_Click");
}

private void grid_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine("grid_Click");
}

...全文
156 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
adodotnet 2010-06-10
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 dobzhansky 的回复:]
没仔细看
感觉应该类似 IE 中的 html 文档对消息的处理

现在 wpf 的消息机制比较全面的是那个 essential 吗?
[/Quote]

呵呵, 我不知道你提到essential是指什么, 不过最近我发现'Essentail Windows Presentation Foundation'这本很薄的书,其实真的相当相当不错。它的中文版的翻译是21世纪的灾难。其实E文版内容组织,知识描述上还是很独到的。
nanhe0065 2010-06-09
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 dobzhansky 的回复:]

赞, 这个层阶的, 唯有如此
[/Quote]
亲爱的, 我们亲一个.
Dobzhansky 2010-06-09
  • 打赏
  • 举报
回复
你何以能保持这种动力的
Dobzhansky 2010-06-09
  • 打赏
  • 举报
回复
赞, 这个层阶的, 唯有如此
nanhe0065 2010-06-09
  • 打赏
  • 举报
回复
加上
btn.AddHandler(UIElement.MouseLeftButtonDownEvent, (RoutedEventHandler)btn_MouseLeftButtonDown, true);
txt.AddHandler(UIElement.MouseLeftButtonDownEvent, (RoutedEventHandler)txt_MouseLeftButtonDown, true);

好了。

event routing continues behind the scenes,呵呵。
nanhe0065 2010-06-09
  • 打赏
  • 举报
回复
去掉Button里的TextBox, 换成这么个layout后,理解上清晰多了。
<Window>
<Grid>
<Button>
<StackPanel>
<Image />
</StackPanel>
</Button>
</Grid>
</Window>


输出:
Window_PreviewMouseLeftButtonDown
grid_PreviewMouseLeftButtonDown
btn_PreviewMouseLeftButtonDown
stack_PreviewMouseLeftButtonDown
img_PreviewMouseLeftButtonDown
img_MouseLeftButtonDown
stack_MouseLeftButtonDown
btn_Click


看这情况btn_MouseLeftButtonDown连执行的机会都没有,直接被转换成Click事件了。。。
nanhe0065 2010-06-09
  • 打赏
  • 举报
回复
还有就是点击Button内的TextBox时,好像不会触发Button.Click事件。所以我怀疑是Button内的TextBox抑制了MouseLeftButtonDown事件(在它内部e.Handled=true),让它无法传递(Bubble)到上一级的Button,继而raise Click event.
Dobzhansky 2010-06-09
  • 打赏
  • 举报
回复
没仔细看
感觉应该类似 IE 中的 html 文档对消息的处理

现在 wpf 的消息机制比较全面的是那个 essential 吗?
nanhe0065 2010-06-09
  • 打赏
  • 举报
回复
是不是可以理解为Button内的TextBox处理了MouseLeftButtonDown事件,并且抑制它继续Route?
Dobzhansky 2010-06-09
  • 打赏
  • 举报
回复
甚至有点继续留在基于 user32 的 message pump 的感觉
太纷繁复杂了
Dobzhansky 2010-06-09
  • 打赏
  • 举报
回复
帮顶
wpf 的事件(消息)模型不懂
好久不看 wpf 了
nanhe0065 2010-06-09
  • 打赏
  • 举报
回复
e.Handled=true;或者UIElement.AddHandler()这个不是我想问的。

先是Tunneling,再Bubbling, 那么至少txt_MouseLeftButtonDown应该执行吧,甚至btn_MouseLeftButtonDown也执行,然后才是Button把MouseLeftButtonDown转换成Click事件,不是这个顺序吗?
皇城龙三 2010-06-09
  • 打赏
  • 举报
回复
控件捕获了MouseLeftButtonDown事件后,会将该事件的"Handled"设置为"true"(这个属性是用在事件路由中的,当某一控件得到一个RoutedEvent,发现他的Handled是true,那么他就会忽略该事件),并且,出发控件本身的Click事件.相当于控件将MouseLeftButtonDown事件"抑制(Supress)"掉了,转换成了Click事件.所以,在这种情况下,我们只有在初始化的时候,利用UIElement的AddHandler方法,显式的为控件增加MouseLeftButtonDown的Handler,具体代码如下:
  myButton.AddHandler(Button.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.OnMouseLeftButtonDownButton), true);

最后一个关键的参数true表明了,无论该事件是否被Handler了(Handled属性被设置为了true),控件都会对该事件进行响应

110,536

社区成员

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

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

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