【问题标题】:Stopping a Control from handling routed events停止控件处理路由事件
【发布时间】:2012-09-27 10:40:44
【问题描述】:

希望是一个简单的问题,因为我刚刚开始处理路由事件。

我有一个自定义的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(),但此时事件已经将Source 设置为MyUserControl,甚至在调用base 或其他任何东西之前。

非常感谢

【问题讨论】:

  • 也许您可以编写一个自定义事件,当引发下部元素中的双击事件时,该事件由 MyContainedControl 引发。然后在您的 MyWindow 中,自定义元素的 OriginalSource 应该是 MyContainedControl1。
  • 向 MyUserControl 添加一个将 EventHandler 作为输入的方法。然后让该方法向 MyContainedControl1-X 注册处理程序。

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


【解决方案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);
        }

【讨论】:

    【解决方案2】:

    也许你可以尝试改变你的 RoutingStrategy。

    http://msdn.microsoft.com/en-us/library/system.windows.routingstrategy.aspx

    【讨论】:

    • 我不提出这个事件。控制可以。
    【解决方案3】:

    我已经设法通过将我的 UserControl 更改为 ContentControl 来解决它。幸运的是,我的内容都是在运行时动态加载的,所以我不需要UserControl 提供的设计时界面。尽管进行了很多搜索,但除了 WPF Unleashed 中的一句话(第 722 页)之外,我找不到任何关于 UserControl 对事件的影响的信息

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

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-22
        • 1970-01-01
        • 2018-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多