这方面的文献很糟糕 - 我想要做的就是从我已经定义的控件中冒出一个事件,但是从代理控制器类中动态创建(希望这不会导致问题).该控件是一个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 ..
}
Run Code Online (Sandbox Code Playgroud)
我希望能在某个地方捕捉到这个事件 - 甚至在我的父窗口或更高的视觉树上.这引用了一个控制器,它包含了通知控件列表 - 我知道哪一个被关闭了,我可以重新编辑/重新绘制任何仍然通过控制器激活的其他控件,但是如何捕获?谢谢!
我同意,关于MSDN上冒泡/隧道的文档并不是很好.
我发现这篇MSDN杂志文章"理解WPF中的路由事件和命令"在解释冒泡事件方面要好得多.
查找"事件路由"部分,复制粘贴如下:
事件路由
了解逻辑树和可视树很重要,因为路由事件主要基于可视树进行路由.路由事件支持Bubble,Tunnel或Direct的RoutingStrategy.
冒泡是最常见的,意味着事件将从源元素冒泡(传播)到可视树中,直到它被处理或到达根元素.这允许您在源元素的元素层次结构上进一步处理对象上的事件.例如,您可以在封闭的Grid元素上附加Button.Click处理程序,而不是直接在按钮本身上.冒泡事件只有表明其动作的名称(例如,MouseDown).
隧道事件从另一个方向开始,从根元素开始并向下遍历元素树,直到它们被处理或到达事件的源元素.这允许上游元素拦截事件并在事件到达源元素之前处理它.隧道事件的名称以"按预期预览"为前缀(例如PreviewMouseDown).
直接事件的行为类似于.NET Framework中的普通事件.该事件唯一可能的处理程序是一个连接到事件的委托.
通常,如果为特定事件定义了Tunnel事件,则会出现相应的Bubble事件.在这种情况下,隧道事件首先触发,从根开始,然后向下到源元素寻找处理程序.一旦处理完或已到达源元素,就会触发Bubble事件,从源元素向上移动并查找处理程序.Bubble或Tunnel事件不会因为调用事件处理程序而停止其路由.如果要停止冒泡或隧道过程,请使用传递的事件参数将事件标记为在事件处理程序中处理:
private void OnChildElementMouseDown(object sender, MouseButtonEventArgs e) { e.Handled = true; }
Run Code Online (Sandbox Code Playgroud)
一旦处理程序将事件标记为已处理,则不会将其提升为任何其他处理程序.嗯,这只是部分正确.在现实中,事件路由继续在幕后,你可以明确地挂钩的事件处理程序代码与具有额外的标志,有效地说出UIElement.AddHandler方法的重写,"叫我即使事件已经被标记为已处理".您可以使用如下调用指定该标志:
m_SomeChildElement.AddHandler(UIElement.MouseDownEvent, (RoutedEventHandler)OnMouseDownCallMeAlways,true);
Run Code Online (Sandbox Code Playgroud)
AddHandler的第一个参数是您要处理的RoutedEvent.第二个是事件处理方法的委托(需要为事件的委托提供正确的签名).第三个参数指示即使另一个处理程序已将事件标记为已处理,您是否仍希望收到通知.您调用AddHandler的元素是在路由期间将监视事件流动的元素.
希望这可以帮助.
在您的父级上,或者您想要处理它的任何地方,您应该能够通过声明在哪个类上声明该事件以及事件名称来处理该事件。对于您的情况,在您的窗口声明中,执行以下操作:
<Window ... FixedTaskbarNotifier.TIMBOO="<EventHandlerName>">
Run Code Online (Sandbox Code Playgroud)
这将捕获所有尚未取消的冒泡事件(如果您愿意,您甚至可以获取这些事件,尽管我认为这不是一个好的做法)。
作为一个简单的示例,创建一个窗口并在其上放置一个按钮。在窗口上,添加单击操作的处理程序(在 ButtonBase 上定义)
<Window ... ButtonBase.Click="Window_Click">
Run Code Online (Sandbox Code Playgroud)
然后,只要单击任何子按钮,即使在子控件等内部,都会触发该事件,除非故意取消该事件。
归档时间: |
|
查看次数: |
2722 次 |
最近记录: |