装饰器体系结构

更新:2007 年 11 月

可视化设计体验需要装饰器,装饰器是设计图面上的特殊标志符号。装饰器通常附加到目标控件,可让用户以图形化方式调整控件的属性。例如,当设计控件时,您会单击控件的一角来调整其大小,您单击的大小调整标志符号就是一个装饰器。

对于 WPF 设计器体系结构来说,能够快速轻松地绘制、完善装饰器,以及重新设置装饰器的样式意义重大。本概述介绍 WPF 设计器装饰器扩展性模型如何使您轻松地创建自己的装饰器来获得自定义控件设计体验。

WPF 设计器为显示装饰器提供了灵活的机制。此机制与一个灵活的命令系统关联,使装饰器可以响应用户输入。可以通过使用 MetadataStore 向控件添加装饰器。

装饰器类型

装饰器几乎可以为所有可视化设计时表示形式建模,但某些装饰器类型出现得更加频繁。下表描述常用装饰器。

装饰器

说明

抓取控点

允许移动和调整控件大小;不可缩放。

轨道

沿控件一侧添加一个标记或标尺;不可沿单个轴缩放。

框架

表示控件的边界;沿两个轴缩放。

覆盖

在控件区域中捕获鼠标交互;沿两个轴缩放。大体上等效于 System.ComponentModel 设计器框架中的主体标志符号。

装饰器特征

WPF 设计器框架启用的装饰器具有下列特征。

  • 允许装饰器从任何 UIElement 类派生并支持 Windows Presentation Foundation 样式。

  • 允许为水平和垂直维度独立指定所有大小、位置和缩放。

  • 不需要装饰器基类。装饰器类型可以从满足需要的任何 UIElement 类型派生。

创建自定义装饰器

装饰器由 AdornerProvider 功能提供程序提供。可以向类添加 AdornerProvider 功能,它会自动将装饰器添加到设计图面中。下面的演练演示如何创建自定义装饰器。

装饰器扩展性

装饰器是根据装饰器提供程序的策略来添加的。可以通过向类定义中添加 UsesItemPolicyAttribute 来向 AdornerProvider 中添加策略。

IsInPolicy 检查通过时,装饰器将显示在设计图面上。

可以向控件添加装饰器提供程序,此控件为给定策略提供装饰器。当策略中的项更改时,装饰器功能连接器在新控件上查询新的装饰器提供程序,并显示更新的装饰器集。

WPF 设计器实现 PrimarySelectionAdornerProvider,它提供一组为主选项显示的装饰器。大多数自定义装饰器提供程序从此类派生。

装饰器和布局

装饰器最重要的问题是布局。装饰器需要各种布局选项。当为设计器图面更改缩放设置时,必须考虑装饰器的特定拉伸或缩放行为。装饰器必须能够根据下面的方案调整自身的大小和位置。

  • 相对于应用的样式。

  • 相对于所装饰控件的大小和位置。

  • 相对于绝对像素偏移量。

  • 相对于当前缩放设置。

在 WPF 中,控制布局的典型机制是面板。WPF 设计器框架通过将 AdornerPanel 类用于设计图面上给定控件的父装饰器来控制布局。

AdornerPanel 类提供的方法允许装饰器相对于装饰器样式指定的大小、所装饰控件的大小或以像素表示的绝对大小来调整大小和位置。这些方法具有累计性,这意味着可以创建的装饰器的偏移量是从相对大小或位置计算的。此类偏移量是以逻辑像素为单位进行设置的,当为设计图面更改缩放设置时,逻辑像素可能缩放也可能不缩放。AdornerPlacementCollection 类型提供用于指定这些关系的方法。

下面的代码示例演示如何在目标控件上定位装饰器。

' Setup the adorner panel.
' All adorners are placed in an AdornerPanel
' for sizing and layout support.
Dim myPanel = Me.Panel

AdornerPanel.SetHorizontalStretch(opacitySlider, AdornerStretch.Stretch)
AdornerPanel.SetVerticalStretch(opacitySlider, AdornerStretch.None)

Dim placement As New AdornerPlacementCollection()

' The adorner's width is relative to the content.
' The slider extends the full width of the control it adorns.
placement.SizeRelativeToContentWidth(1.0, 0)

' The adorner's height is the same as the slider's.
placement.SizeRelativeToAdornerDesiredHeight(1.0, 0)

' Position the adorner above the control it adorns.
placement.PositionRelativeToAdornerHeight(-1.0, 0)

' Position the adorner up 5 pixels. This demonstrates 
' that these placement calls are additive. These two calls
' are equivalent to the following single call:
' PositionRelativeToAdornerHeight(-1.0, -5).
placement.PositionRelativeToAdornerHeight(0, -5)

AdornerPanel.SetPlacements(opacitySlider, placement)
// Setup the adorner panel.
// All adorners are placed in an AdornerPanel
// for sizing and layout support.
AdornerPanel myPanel = this.Panel;

AdornerPanel.SetHorizontalStretch(opacitySlider, AdornerStretch.Stretch);
AdornerPanel.SetVerticalStretch(opacitySlider, AdornerStretch.None);

AdornerPlacementCollection placement = new AdornerPlacementCollection();

// The adorner's width is relative to the content.
// The slider extends the full width of the control it adorns.
placement.SizeRelativeToContentWidth(1.0, 0);

// The adorner's height is the same as the slider's.
placement.SizeRelativeToAdornerDesiredHeight(1.0, 0);

// Position the adorner above the control it adorns.
placement.PositionRelativeToAdornerHeight(-1.0, 0);

// Position the adorner up 5 pixels. This demonstrates 
// that these placement calls are additive. These two calls
// are equivalent to the following single call:
// PositionRelativeToAdornerHeight(-1.0, -5).
placement.PositionRelativeToAdornerHeight(0, -5);

AdornerPanel.SetPlacements(opacitySlider, placement);

缩放行为

当设计器视图的缩放设置更改为 200% 时,所装饰控件以实际大小的两倍呈现。所有距离和字体更大,线条更粗。许多装饰器设计指定装饰器保留它们的原始大小,即使设计器视图缩放更改时也是如此。

布局空间和呈现空间

在 WPF 设计器中,可以将控件相对于两个不同的参考框架(布局空间和呈现空间)放置在设计图面上。

布局空间定义在 WPF 布局系统计算设计的布局时控件占据了多少空间。呈现空间定义在计算了布局以及应用了所有呈现转换后控件占据了多少空间。有关更多信息,请参见布局空间和呈现空间

DesignerView

DesignerView 类提供了一个装饰器集合,并将所有用户输入映射到设计器操作。DesignerView 类是从 Decorator 类派生的。它为设计器提供一个可视化图面。将设计器 UI 的根元素分配给 DesignerViewChild 属性,并在设计器视图上设置编辑上下文属性,使其指向设计器的编辑上下文。

DesignerView view = new DesignerView();
view.Child = documentManager.View;
view.Context = editingContext;

DesignerView 类实现 WPF 设计器的两个方面。

装饰器

DesignerView 类支持在视图中使用其他可视化装饰(这些装饰会覆盖正在设计的控件)来装饰元素。

输入传送

DesignerView 类将用户输入传送给装饰器、工具和任务中的命令。

DesignerView 类通过在所有内容前面引入两个附加元素(即装饰器层和命中测试层)来工作。下图演示设计器视图层和可视化树之间的关系。

设计器视图

DesignerView 类有一个可在 XAML 中使用的空构造函数。

请参见

任务

演练:创建设计时装饰器

参考

AdornerPanel

AdornerProvider

DesignerView

其他资源

WPF 设计器扩展性