c# - 难倒 - 在 WPF 中将 routedevent 冒泡到顶部窗口 - 如何在任何地方捕获!

标签 c# wpf

这方面的文献很糟糕——我只想从我定义但在代理 Controller 类中动态创建(希望这不会导致问题)的控件中冒出一个事件。该控件是一个 PopUp。

public static readonly RoutedEvent weClosed = EventManager.RegisterRoutedEvent("TIMBOO", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(FixedTaskbarNotifier));


    // Provide CLR accessors for the event
    public event RoutedEventHandler TIMBOO
    {
        add { AddHandler(weClosed, value); }
        remove { RemoveHandler(weClosed, value); }
    }

    // This method raises the Tap event
    void RaiseTapEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(weClosed);
        RaiseEvent(newEventArgs);}


    protected override void OnClosed(EventArgs e)
    {
        //TO DO - rearrange current open windows - fire event?
        Log.Instance.Info("Clean up Window");
        RaiseTapEvent(); This is called on close but nothing fires ..
                }

我希望在某处捕获事件 - 即使是在我的父窗口中或可视化树的更高层。这引用了一个包含通知控件列表的 Controller ——一旦我知道哪个被关闭,我就可以通过 Controller 重新组织/重新绘制任何其他仍然事件的,但是如何捕捉? 谢谢!

最佳答案

我同意,MSDN 上关于冒泡/隧道的文档一点也不好。

我找到了这篇 MSDN 杂志文章 "Understanding Routed Events and Commands In WPF"更善于解释冒泡事件。

查找“事件路由”部分,复制粘贴如下:

Event Routing

Understanding a little about the logical and visual trees is important because routed events get routed based primarily on the visual tree. Routed events support a RoutingStrategy of Bubble, Tunnel, or Direct.

Bubble is the most common and means that an event will bubble (propagate) up the visual tree from the source element until either it has been handled or it reaches the root element. This allows you to handle an event on an object further up the element hierarchy from the source element. For example, you could attach a Button.Click handler on the enclosing Grid element instead of directly on the button itself. Bubble events just have names that indicate their action (for example, MouseDown).

Tunnel events go in the other direction, starting at the root element and traversing down the element tree until they are handled or reach the source element for the event. This allows upstream elements to intercept the event and handle it before the event reaches the source element. Tunnel events have their names prefixed with Preview by convention (such as PreviewMouseDown).

Direct events behave like normal events in the .NET Framework. The only potential handler for the event is a delegate that is hooked up to the event.

Usually if a Tunnel event is defined for a particular event, there is a corresponding Bubble event. In that case, the Tunnel event fires first, starting at the root and working its way down to the source element looking for a handler. Once it has been handled or has reached the source element, the Bubble event is fired, working its way up from the source element and looking for a handler. A Bubble or Tunnel event does not stop its routing just because an event handler is called. If you want to stop the bubbling or tunneling process, you mark the event as handled in your event handler using the event arguments you are passed:

private void OnChildElementMouseDown(object sender, MouseButtonEventArgs e) { e.Handled = true; }

Once your handler marks an event as handled, it will not be raised to any more handlers. Well, that is only partially true. In reality, event routing continues behind the scenes, and you can explicitly hook up event handlers in code with an override of the UIElement.AddHandler method that has an additional flag to effectively say, "Call me even if the event has been marked as handled." You specify that flag with a call like the following:

m_SomeChildElement.AddHandler(UIElement.MouseDownEvent, (RoutedEventHandler)OnMouseDownCallMeAlways,true);

The first parameter to AddHandler is the RoutedEvent you want to handle. The second is a delegate to the event-handling method (which will need to have the correct signature for the event's delegate). The third parameter indicates whether you want to be notified even if another handler has marked the event as handled. The element on which you call AddHandler is the one that will be watching for the event to flow by during routing.

希望这对您有所帮助。

关于c# - 难倒 - 在 WPF 中将 routedevent 冒泡到顶部窗口 - 如何在任何地方捕获!,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2379359/

相关文章:

c# - 将 C# 数组传递给 C++ 方法

c# - TextBox TextChanged 事件问题

c# - 如何更改整个 Canvas 的鼠标光标形状?

c# - 如何使用 PushSharp 获取 GCM 错误消息 'NotRegistered'

c# - 编写 Linq2Xml 查询时出现问题

c# - 您将如何在 Java 或 C# 中编写高效的循环缓冲区?

c# - 如何在 WinRT XAML 中的值发生变化时为 TextBlock 设置动画?

c# - 非 UI 线程上的 WPF 调度程序

wpf - 在 ViewModel 中获取窗口属性

c# - Awesomium 网页控制