我什么时候应该使用装饰品?

时间:2010-04-07 19:08:43

标签: wpf adorner

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

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

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

谢谢

1 个答案:

答案 0 :(得分:75)

对于大多数用途,Adorners比使用ControlTemplates需要更多的工作。如果您想要装饰者提供的其他功能,请使用它们。否则使用ControlTemplates。

以下是Adorners提供的主要功能:

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

    1. 您必须编写代码才能调用.GetAdornerLayer().Add()并管理Adorner的生命周期
    2. 您必须为您的Adorner编写渲染代码,或添加代码以包含Control作为装饰者的子级,以便您可以使用ControlTemplate
    3. 您通常会在代码中进行自定义度量/排列计算(除非您在装饰器中使用ControlTemplate)
    4. 如果您希望目标控件处理它们,则需要将RoutedEvents转发给AdornedElement
    5. 如果要将DataContext带到
    6. ,则需要添加DataContext="{Binding AdornedElement.DataContext}"
    7. 在每个布局通道上都会扫描可见的Adorner,因此一次在屏幕上显示数千个装饰器会导致明显的减速。 (普通视觉效果只有当直接影响它们的东西发生变化时才会调用它们的度量/排列代码。)
    8. Having more than 144 adorners is not supported,因此如果有接近此限制的风险,控制模板会更合适。
    9. 在您的特定示例中,没有明确的正确答案。

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

      • 如果线条不是简单的直线,那么自动定位的标签可能非常适合测量/排列计算的角度,但如果您可能会同时看到其中的一万条我会担心表现。

      在不了解您的应用程序的情况下,很难说除此之外。