我啥时候应该使用装饰器?
Posted
技术标签:
【中文标题】我啥时候应该使用装饰器?【英文标题】:When should I use adorners?我什么时候应该使用装饰器? 【发布时间】:2010-04-07 19:08:43 【问题描述】:WPF 很棒,因为有很多方法可以实现您的目标。例如,据我了解,装饰者可以向 UI 元素添加一些控件,但我认为可以通过包含附加元素的自定义控件来实现相同的行为。
所以,我的问题是:我什么时候应该更喜欢装饰器而不是更复杂(但我认为更灵活)的自定义控件? 请考虑我正在广泛使用 MVVM 模式,并且我想将命令绑定到附加元素。
特别是,我正在设计一个图表设计器应用程序,我想为我的形状添加连接点。另一个我应该在自定义控件和装饰器之间做出决定的例子是一行,它显示了一个自动定位为“跟随”该行的标签。
谢谢
【问题讨论】:
【参考方案1】:在大多数情况下,装饰器比使用 ControlTemplates 需要更多的工作。如果您想要装饰器提供的附加功能,请使用它们。否则使用 ControlTemplates。
以下是 Adorners 带来的主要功能:
-
由于装饰器位于单独的图层上,因此视觉效果可以延伸到装饰元素之外,即使装饰元素被剪裁也是如此。
由于装饰器位于单独的层上,它们通常不会被 AdornedElement 的容器或同级控件遮挡。
装饰元素的大小和位置的所有变化都会自动通知装饰者,从而允许对普通控件无法轻松实现的布局变化做出响应。
装饰器可以应用于面板和现有控件,而无需对其模板或其他方式进行任何更改。这使得它们非常适合为任意控件提供操作句柄或视觉反馈。
在许多情况下,您只会为成百上千的少数“活跃”物品创建装饰器。如果您必须向模板添加一个额外的面板,使用 ControlTemplates 实现相同的功能可能会大大降低效率:模板的每个实例都会有一个额外的面板,而只有一个装饰器。
以下是与使用装饰器而非 ControlTemplates 相关的一些潜在成本:
-
您必须编写代码来调用
.GetAdornerLayer()
和 .Add()
并管理 Adorner 的生命周期
您必须为您的 Adorner 编写渲染代码或添加代码以包含 Control
作为 adorner 的子项,以便您可以将 ControlTemplate 与它一起使用
您通常会在代码中进行自定义度量/排列计算(除非您在装饰器中使用 ControlTemplate)
如果您希望目标控件处理它们,则需要将 RoutedEvents
转发到 AdornedElement
如果您想引入 DataContext,则需要添加 DataContext="Binding AdornedElement.DataContext"
似乎在每个布局通道上都会扫描可见的装饰器,因此同时在屏幕上显示数千个装饰器可能会导致明显的减速。 (普通视觉只有在直接影响它们的事物发生变化时才会调用它们的测量/排列代码。)
Having more than 144 adorners is not supported,所以如果有接近这个限制的风险,控制模板会更合适。
在你的具体例子中,没有明确的正确答案。
我倾向于使用 ControlTemplate 作为连接点,因为您可能需要一种方法来指定连接点的位置,并且 ControlTemplate 已经定义了项目本身的布局。另一方面,如果连接点信息是数据驱动的并且只出现在活动控件(或被拖动的控件)上,那么使用装饰器可能会更好地获得性能优势并简化各个 ControlTemplates。
如果线条不是简单的直线,那么从测量/排列计算的角度来看,自动定位的标签可能非常适合装饰器,但如果您可能会同时看到一万条这样的标签我会担心性能。
如果不了解您的应用程序的更多信息,很难说比这更多。
【讨论】:
非常感谢,这是一个很好的完整答案。该应用程序是一个UML设计器,所以我认为我不会有太多的连接;无论如何,它们通常不是直线。以上是关于我啥时候应该使用装饰器?的主要内容,如果未能解决你的问题,请参考以下文章