阻止Control处理路由事件

时间:2012-09-27 10:40:45

标签: c# wpf user-controls event-handling routed-events

希望这是一个简单的问题,因为我正在处理路由事件。

我有自定义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

我已尝试在OnMouseDoubleClick()中覆盖OnPreviewMouseDoubleClick()MyUserControl,但此时事件已经将源设置为MyUserControl,甚至在调用base或任何内容之前。< / p>

非常感谢

4 个答案:

答案 0 :(得分:1)

我只是像这样走在视觉树上:

        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);
        }

答案 1 :(得分:0)

答案 2 :(得分:0)

我已设法通过将UserControl更改为ContentControl来修复此问题。幸运的是,我的内容都是在运行时动态加载的,因此我不需要UserControl提供的设计时间表面。尽管搜索很多,我找不到任何有关UserControl对事件的影响,除了WPF Unleashed中的一个句子(第722页)

  

那是因为UserControl与ContentControl的区别很小   基类;它有一个不同的默认控件模板,它有一个   拉伸的默认内容对齐方向(而不是   Left和Top),它默认将IsTabStop和Focusable设置为false,   并且它会将从内部内容引发的任何事件的来源更改为   是UserControl本身

我还必须更改为使用PreviewMouseDown而不是MouseDoubleClick,因为MouseDoubleClick不是真正的冒泡事件。见Control.MouseDoubleClick

  

虽然这个路线事件似乎遵循一条冒泡的路线   元素树,它实际上是一个引发的直接路由事件   每个UIElement沿着元素树。

如果我需要UserControl,那么我认为我必须按照Klaus78建议并在ContainedControl中提升我自己的自定义事件,或者手动订阅每个ContainedControl上的双击事件而不是让它他们冒泡了。

答案 3 :(得分:-1)

您可以使用jquery event.preventDefault() API。