希望这是一个简单的问题,因为我刚刚掌握了路由事件。
我有一个自定义的UserControl
。它包含许多其他控件。
在我的树上,我想对源自其中一个包含的控件(而不是我的UserControl
)的双击事件做出响应。但是,我的UserControl
显然正在捕获事件并将source
属性设置为自己。我怎么能阻止它这么做?
我不能使用OriginalSource
,因为这指向单击的最低级别控件(Border
或其他)。
例如。
MyWindow <--- Want to handle double click here with Source = MyContainedControl1
|
+-MyUserControl (this is setting Source to itself. How do I turn this off?)
|
+-MyContainedControl1
|
Border <---- Mouse double clicks here
EditBox
Etc
我已经尝试在MyUserControl
中重写OnMouseDoubleClick()
和OnPreviewMouseDoubleClick()
,但此时事件甚至在调用base或任何东西之前就已经将Source设置为MyUserControl
。
非常感谢
我会这样走视觉树:
private void Window_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var control = FindVisualParent<MyContainedControl1>(e.OriginalSource as DependencyObject);
if (control != null)
{
//magic happens here
}
}
public static T FindVisualParent<T>(DependencyObject child) where T : DependencyObject
{
var parent = VisualTreeHelper.GetParent(child);
if (parent == null)
return null;
T pT = parent as T;
return pT != null ? pT : FindVisualParent<T>(parent);
}
您可以尝试更改您的RoutingStrategy。
http://msdn.microsoft.com/en-us/library/system.windows.routingstrategy.aspx
我通过将UserControl
改为ContentControl
来修复它。幸运的是,我的内容都是在运行时动态加载的,所以我不需要UserControl
提供的设计时表面。尽管进行了大量搜索,但除了WPF Unleashed(第722页)中的一句话外,我找不到任何关于UserControl对事件的影响的信息
这是因为UserControl与其ContentControl差别很小基类;它有一个不同的默认控件模板,它有双向拉伸的默认内容对齐方式(而不是Left和Top),默认情况下将IsTabStop和Focusable设置为false,并且它将从内部内容引发的任何事件的源更改为是UserControl本身。
我还不得不改为使用PreviewMouseDown
而不是MouseDoubleClick
,因为MouseDoubleClick不是一个真正的冒泡事件。请参阅控制。鼠标双击:
尽管此路由事件似乎遵循通过元素树,它实际上是一个直接路由的事件每个UIElement沿着元素树。
如果我需要UserControl
,那么我想我必须按照Klaus78的建议,在ContainerControl中引发我自己的自定义事件,或者手动订阅每个ContainerControl上的双击事件,而不是让它们冒泡。
您可以使用jquery event.prventDefault()API进行此操作。