53

WPF 很棒,因为有很多方法可以实现您的目标。例如,据我了解,装饰者可以向 UI 元素添加一些控件,但我认为可以通过包含附加元素的自定义控件来实现相同的行为。

所以,我的问题是:我什么时候应该更喜欢装饰器而不是更复杂(但我认为更灵活)的自定义控件?请考虑我正在广泛使用 MVVM 模式,并且我想将命令绑定到附加元素。

特别是,我正在设计一个图表设计器应用程序,我想为我的形状添加连接点。我应该在自定义控件和装饰器之间做出决定的另一个示例是一条线,它显示了一个自动定位为“跟随”该线的标签。

谢谢

4

1 回答 1

85

在大多数情况下,装饰器比使用 ControlTemplates 需要更多的工作。如果您想要装饰器提供的附加功能,请使用它们。否则使用 ControlTemplates。

以下是 Adorners 带来的主要功能:

  1. 因为装饰器位于单独的层上,所以视觉效果可以延伸到装饰元素之外,即使装饰元素被剪裁。
  2. 因为装饰器位于单独的层上,所以它们通常不会被 AdornedElement 的容器或同级控件遮挡。
  3. 装饰元素的大小和位置的所有变化都会自动通知装饰者,从而允许对使用普通控件无法轻松实现的布局更改做出响应。
  4. 装饰器可以应用于面板和现有控件,而无需对其模板或其他方式进行任何更改。这使得它们非常适合在任意控件上提供操作句柄或视觉反馈。
  5. 在许多情况下,您只会为数百或数千个“活动”项目创建装饰器。如果您必须向模板添加一个额外的面板,使用 ControlTemplates 实现相同的功能可能会大大降低效率:模板的每个实例都会有一个额外的面板,而只有一个装饰器。

以下是与使用装饰器而不是 ControlTemplates 相关的一些潜在成本:

  1. 您必须编写代码来调用.GetAdornerLayer().Add()管理 Adorner 的生命周期
  2. 您必须为您的 Adorner 编写渲染代码或添加代码以包含 aControl作为 adorner 的子项,以便您可以将 ControlTemplate 与它一起使用
  3. 您通常会在代码中进行自定义度量/排列计算(除非您在装饰器中使用 ControlTemplate)
  4. RoutedEvents如果您希望它们由目标控件处理,则需要转发到 AdornedElement
  5. DataContext="{Binding AdornedElement.DataContext}"如果您想将 DataContext 带入,则需要添加
  6. 似乎在每个布局通道上都会扫描可见的装饰器,因此同时在屏幕上显示数千个装饰器可能会导致明显的减速。(普通的视觉效果只有在直接影响它们的东西发生变化时才会调用它们的测量/排列代码。)
  7. 不支持超过 144 个装饰器,因此如果存在接近此限制的任何风险,则控制模板更适合。

在您的特定示例中,没有明确的正确答案。

  • 我倾向于将 ControlTemplate 用于连接点,因为您可能需要一种方法来指定连接点的位置,并且 ControlTemplate 已经定义了项目本身的布局。另一方面,如果连接点信息是数据驱动的并且仅出现在活动控件(或被拖动的控件)上,则使用装饰器可能会更好地获得性能优势并简化各个 ControlTemplates。

  • 如果线条不是简单的直线,那么从测量/排列计算的角度来看,自动定位的标签可能非常适合装饰器,但是如果您可能同时看到一万条这样的标签,我会担心性能.

在不了解您的应用程序的情况下,很难说更多。

于 2010-04-09T23:34:14.080 回答