尽管可在任意WPF项目中编写自定义元素,但通常希望在专门的类库程序集(DLL)中放置自定义元素。这样,可在多个WPF应用程序之间共享自定义元素。
为确保具有正确的程序集引用和名称空间导入,当在Visual Studio中创建应用程序时,应当选择Custom Control Library(WPF)项目类型。在类库中,可创建任意数量的控件。
创建自定义控件的第一步是选择正确的基类进行继承。下表列出了创建自定义控件时一些常用的基类。
名 称 | 说 明 |
FrameworkElement | 当创建自定义元素时,这是最常用的最低级的基类。通常,只有当希望重写OnRender()方法并使用System.Windows.Media.DrawingContext从头绘制内容时,才会使用这种方法。 |
Control | 当从头开始创建控件时,这是最常用的起点。该类是所有用户交互小组件的基类。Control类添加了用于设置背景、前景、字体和内容对齐方式的属性。控件类还为自身设置了Tab顺序(通过IsTabStop属性),并且引入了鼠标双击功能(通过MouseDoubleClick和PreviewMouseDoubleClick属性)。但最重要的是,Control类定义了Template属性,为了得到无限的灵活性。该属性允许使用自定义元素树替换其外观。 |
ContentControl | 这是能够显示任意单一内容的控件的基类。显示的内容可以是元素或结合使用模板的自定义对象(内容通过Content属性设置,并且可以通过ContentTemplate属性提供可选的模板)。许多控件都封装了特定的、类型在一定范围内的内容(例如,文本框中的文本字符串)。因此这些控件不支持所有元素,所以不是内容控件。 |
UserControl | 这是可使用设计视图进行配置的内容控件。尽管用户控件和普通的内容控件是不同的,但当希望在多个窗口中快速重用用户界面中的不变模块时(而不是创建真正的能在不同应用程序之间转移的独立控件),通常使用该基类 |
ItemControl或 Selector |
ItemsControl是封装项列表的控件的基类,但不支持选择,而Selector类是支持选择的控件的更具体基类。创建自定义控件不经常使用这些类,因为ListBox、ListView以及TreeView控件的数据绑定特性提供了很大的灵活性 |
Panel | 该类是具有布局逻辑控件的基类。布局控件能够包含多个子元素,并根据特定的布局语义安排这些子元素。通常,面板提供了用于设置子元素的附加属性,配置如何安排子元素 |
Decorator | 封装其他元素的元素基类,并且提供了一种图形效果或特定的功能。两个明显的例子是Border和ViewBox,其中Border控件在元素的周围绘制线条,ViewBox控件使用变换动态缩放其内容。其他修饰元素包括为普通控件(如按钮)提供熟悉边框和背景色的修饰类 |
特殊控件类 | 如果希望改进现有控件,可直接继承该控件。例如,可创建具有内置验证逻辑的TextBox控件。然而,在采取这一步之前,应当首先分析是否可通过事件处理代码或单独的组件达到同一目的。这两种方法都可使自定义逻辑和控件相分离,从而可在其他控件中重用 |
接下来将看到一个用户控件,一个直接继承自Contrl类的无外观的颜色拾取器,一个使用可视化状态的无外观的的FlipPanel,一个自定义的布局面板,以及一个继承自FrameworkElement类并重写了OnRender()方法的自绘制元素。