gpt4 book ai didi

c# - WPF 附加事件与非附加事件

转载 作者:IT王子 更新时间:2023-10-29 04:22:17 28 4
gpt4 key购买 nike

问题是,经过我所有的研究,我仍然找不到常规路由事件和附加事件之间的区别。功能上有什么区别?或者其他人是否同意没有?

实现

ButtonBase 类声明了一个名为 ClickEvent 的路由事件;一个正常的路由事件。

public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));

[Category("Behavior")]
public event RoutedEventHandler Click
{
add
{
base.AddHandler(ClickEvent, value);
}
remove
{
base.RemoveHandler(ClickEvent, value);
}
}

Mouse 类声明了一个名为 MouseDownEvent 的路由事件;附加事件。

public static readonly RoutedEvent MouseDownEvent = EventManager.RegisterRoutedEvent("MouseDown", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(Mouse));

public static void AddMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
UIElement.AddHandler(element, MouseDownEvent, handler);
}

public static void RemoveMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler)
{
UIElement.RemoveHandler(element, MouseDownEvent, handler);
}

这两个事件都在 EventManager 中注册,并以相同的方式存储为公共(public)的、静态的、只读的字段。 ClickEvent 有一个支持 CLR 事件字段,带有自定义添加和删除访问器,分别调用 base.AddHandler 和 base.RemoveHandler;两者都在 ButtonBase 派生的 UIElement 基类中声明。 MouseDownEvent 有两个静态方法 AddMouseDownHandler 和 RemoveMouseDownHandler,它们最终调用在 UIElement 中声明的相同的两个 AddHandler 和 RemoveHandler 方法,就像 ClickEvent 一样。

在静态类上声明的实际附加事件的 Add*Handler 和 Remove*Handler 静态方法必须遵循特定的命名约定,以允许 WPF 事件系统使用反射在运行时找到适当的添加和删除处理程序。


用法

这两个事件都可以在 XAML 中附加处理程序,如下所示:

<Grid Button.Click="Grid_Click"
Mouse.MouseDown="Grid_MouseDown">
</Grid>

这两个事件都可以附加在代码中,如下所示:

// Attach ClickEvent handler.
myGrid.AddHandler(Button.ClickEvent, new RoutedEventHandler(Grid_Click));

// Attach MouseDownEvent handler.
Mouse.AddMouseDownHandler(myGrid, Grid_MouseDown);

如您所见,这两个事件都可以附加到不拥有或声明它们的元素。


结论 - 什么是附加事件?

MSDN 文档指出: http://msdn.microsoft.com/en-us/library/bb613550.aspx

Extensible Application Markup Language (XAML) defines a language component and type of event called an attached event. The concept of an attached event enables you to add a handler for a particular event to an arbitrary element rather than to an element that actually defines or inherits the event. In this case, neither the object potentially raising the event nor the destination handling instance defines or otherwise "owns" the event.

此外,用于考试 70-511 的官方 MCTS 培训套件 - 使用 Microsoft .NET Framework 4 开发 Windows 应用程序指出:

It is possible for a control to define a handler for an event that the control cannot itself raise. These incidents are called attached events. For example, consider Button controls in a grid. The Button class defines a Click event, but the Grid class does not. However, you can still define a handler for buttons in the grid by attaching the Click event of the Button control in the XAML code.

术语“附加事件”似乎在整个 Microsoft 学习资源中都模糊不清,尽管很明显这里有两个不同但密切相关的概念:附加事件和 XAML 附加事件语法。我引用的两个 Microsoft 来源似乎都指的是 XAML 附加事件语法,而不是实际的附加事件。但是,附加事件概述 MSDN 页面继续向您展示如何实现实际的附加事件,而培训工具包则没有。

Mouse.MouseDownEvent 是在具有相应静态添加和删除处理程序的静态类上声明的路由事件的示例,也称为附加事件。但是,ButtonBase.ClickEvent 是一个普通的路由事件,尽管它仍然可以与 XAML 附加事件语法一起使用,方式与实际附加事件相同。

实际附加事件的目的是它允许开发人员为现有的 UIElement 派生类声明新的路由事件,而不必对它们进行子类化;这意味着您可以只附加新的路由事件,而无需它们实际存在于您想要引发或处理它们的类中。但是,等等……这难道不是纯路由事件的首要目的吗?

MSDN 上的路由事件概述页面指出:http://msdn.microsoft.com/en-us/library/ms742806.aspx

Functional definition: A routed event is a type of event that can invoke handlers on multiple listeners in an element tree, rather than just on the object that raised the event.

从该功能定义看来,任何路由事件本质上都提供与附加事件完全相同的功能。所以基本上,附加事件实际上只是一种在静态类上声明路由事件的方法,与普通路由事件相比并没有真正提供任何好处。

让我知道你的想法,因为我可能在这里遗漏了一些东西。

谢谢,蒂姆·瓦伦丁

最佳答案

区别主要在于句法,两个委托(delegate)引用都由 WPF 的 EventManager 处理,但是附加事件使您能够声明通用功能,而无需膨胀所有类的实现。

在正常路由事件的情况下,该类提供了接口(interface),以便能够在某个时候通过调用事件处理程序来响应事件。但是 WPF 只需要知道它是否是从给定类型派生的对象以及是否已注册处理程序。这意味着我们可以制作更简单的类层次结构,并且还支持开闭原则(Open to Extension,Closed to Modification)。通过这种方式,程序员可以定义几个类应该具有的新行为,而无需修改原始类。

另见 Attached Properties

关于c# - WPF 附加事件与非附加事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6198184/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com