WPF中的类监听器和实例列表器有什么区别?

时间:2022-02-16 13:21:42

I am trying to wrap my head around some WPF specific stuff, and have yet to find the concrete relation between the UIElement.AddHandler method and the EventManager.RegisterClassHandler method.

我试图用一些WPF特定的东西来描述我的想法,但是还没有找到UIElement之间的具体关系。AddHandler方法和EventManager。RegisterClassHandler方法。

I have googled a bit and found this interesting MSDN article:

我在谷歌上搜索了一下,发现了这篇有趣的MSDN文章:

http://msdn.microsoft.com/en-us/library/ms747183.aspx

http://msdn.microsoft.com/en-us/library/ms747183.aspx

Here it states:

这状态:

"Routed events consider two different types of listeners to the event: class listeners and instance listeners. Class listeners exist because types have called a particular EventManager API, RegisterClassHandler, in their static constructor, or have overridden a class handler virtual method from an element base class. Instance listeners are particular class instances/elements where one or more handlers have been attached for that routed event by a call to AddHandler."

路由事件考虑到事件的两种不同类型的侦听器:类侦听器和实例侦听器。类侦听器的存在是因为类型在其静态构造函数中调用了特定的EventManager API、RegisterClassHandler,或者从元素基类中重写了类处理程序虚拟方法。实例侦听器是特定的类实例/元素,其中一个或多个处理程序通过调用AddHandler来连接到该路由事件。

Alright now so i know the difference between a class and its instance, but somehow i cannot make sense out of this specific part of the document.

好了,现在我知道了类和它的实例之间的区别,但不知何故,我无法理解文档的这个特定部分。

Can anyone clear that up for me?

谁能帮我澄清一下吗?

1 个解决方案

#1


11  

I don't know, what exactly do you want to know. Things are pretty simple: you can register handler at instance (object) level, or at class level.

我不知道,你到底想知道什么。事情非常简单:您可以在实例(对象)级别或类级别注册处理程序。

The difference is, when you register event at class level, it will get called first, before any instance level handlers (of course tunneling or bubbling still takes place before, if handling class is lower/higher in logical tree). So you can handle this event at class level and filter whether this event should be handled by instance or not (by setting e.Handled = true you will stop event for going through other handlers). It may be useful in some cases, but for now I have no example in my mind to share.

不同之处在于,当您在类级别注册事件时,它将首先被调用,在任何实例级处理程序之前(当然,如果处理类在逻辑树中较低/较高,那么在此之前仍然会发生隧道或冒泡)。因此,您可以在类级别处理此事件,并筛选该事件是否应该由实例处理(通过设置e)。处理= true,您将停止事件以通过其他处理程序)。在某些情况下,它可能是有用的,但现在我没有任何可以分享的例子。

This sample will register event handler that will be called only when event was raised for specific instance of element:

本示例将注册事件处理程序,该处理程序仅在针对元素的特定实例引发事件时调用:

DockPanel panel = new DockPanel();
panel.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));

And this will create event handler, that will be called each time any DockPanel will get Button.Click event, before instance handler of this DockPanel will get called:

这将创建事件处理程序,每次DockPanel获取按钮时都会调用它。单击event,在调用这个DockPanel的实例处理程序之前:

EventManager.RegisterClassHandler(typeof(DockPanel),
    Button.ClickEvent, new RoutedEventHandler(ButtonClass_Click));

If methods were:

如果方法:

private void ButtonClass_Click(object sender, RoutedEventArgs e)
{
    Debug.Write("Class level handler");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    Debug.Write("Instance level handler");
}

This would create output:

这将创建输出:

Class level handler
Instance level handler

类级处理程序实例级处理程序

But if in class level handler you would set event args to handeled (e.Handled = true;), it would filter out this event for instance level handler (and bubbling up in logical tree).

但是如果在类级处理程序中,您会将事件args设置为手工处理(e)。它将为实例级处理程序过滤掉这个事件(并在逻辑树中冒泡)。

#1


11  

I don't know, what exactly do you want to know. Things are pretty simple: you can register handler at instance (object) level, or at class level.

我不知道,你到底想知道什么。事情非常简单:您可以在实例(对象)级别或类级别注册处理程序。

The difference is, when you register event at class level, it will get called first, before any instance level handlers (of course tunneling or bubbling still takes place before, if handling class is lower/higher in logical tree). So you can handle this event at class level and filter whether this event should be handled by instance or not (by setting e.Handled = true you will stop event for going through other handlers). It may be useful in some cases, but for now I have no example in my mind to share.

不同之处在于,当您在类级别注册事件时,它将首先被调用,在任何实例级处理程序之前(当然,如果处理类在逻辑树中较低/较高,那么在此之前仍然会发生隧道或冒泡)。因此,您可以在类级别处理此事件,并筛选该事件是否应该由实例处理(通过设置e)。处理= true,您将停止事件以通过其他处理程序)。在某些情况下,它可能是有用的,但现在我没有任何可以分享的例子。

This sample will register event handler that will be called only when event was raised for specific instance of element:

本示例将注册事件处理程序,该处理程序仅在针对元素的特定实例引发事件时调用:

DockPanel panel = new DockPanel();
panel.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));

And this will create event handler, that will be called each time any DockPanel will get Button.Click event, before instance handler of this DockPanel will get called:

这将创建事件处理程序,每次DockPanel获取按钮时都会调用它。单击event,在调用这个DockPanel的实例处理程序之前:

EventManager.RegisterClassHandler(typeof(DockPanel),
    Button.ClickEvent, new RoutedEventHandler(ButtonClass_Click));

If methods were:

如果方法:

private void ButtonClass_Click(object sender, RoutedEventArgs e)
{
    Debug.Write("Class level handler");
}

private void Button_Click(object sender, RoutedEventArgs e)
{
    Debug.Write("Instance level handler");
}

This would create output:

这将创建输出:

Class level handler
Instance level handler

类级处理程序实例级处理程序

But if in class level handler you would set event args to handeled (e.Handled = true;), it would filter out this event for instance level handler (and bubbling up in logical tree).

但是如果在类级处理程序中,您会将事件args设置为手工处理(e)。它将为实例级处理程序过滤掉这个事件(并在逻辑树中冒泡)。