在WPF中编写自定义控件的“最佳实践”是什么?

时间:2009-08-20 09:13:19

标签: wpf custom-controls

我已经开始为高度可视化的项目编写一些自定义控件。我想知道在编写WPF自定义控件时你的“最佳实践”是什么?

5 个答案:

答案 0 :(得分:3)

如果您可以在不更改其含义的情况下执行此操作,则保持属性名称与内置控件的属性名称相同。

e.g。如果您有CustomerDisplayer自定义控件,请不要调用客户列表客户,将其称为ItemsSource。

起初看起来可能看起来很反直,但从长远来看它可以省去很多麻烦,因为未来的程序员可以对名为ItemsSource的属性如何行为做出很多假设,而这些属性不一定会对Customers属性产生影响。

答案 1 :(得分:3)

如果您希望自定义控件支持这样的直接内容:

<CustomObject>
    Direct content example 1
</CustomObject>

<!-- or -->

<CustomObject>
    <Button Content="Direct content example 2" />
</CustomObject>

然后你需要使用ContentPropertyAttribute告诉WPF当你写这样的xaml时,实际上正在设置哪个属性。

该属性可以这样使用:

[ContentProperty("NameOfProperty")]
public class CustomObject
{
    [...]

ContentControl使用此属性设置Content属性,但请注意该属性可以被调用任何内容;例如,WPF TextBox使用此属性来设置Text属性。

E.G。

[ContentProperty("Text")]

该属性也必须是依赖属性(有关此证据,请参阅MSDN文档示例)。

最后,此属性特定于xaml解析器,而不是ContentControl,并且可以与上面的TextBox示例中可以看到的任何类型一起使用(TextBox未派生来自ContentControl)。

答案 2 :(得分:2)

确保可以重新设置控件并重新模板化控件,而无需更改控件的操作方式。不要让控件假设列表框和按钮都在同一个面板中,或者甚至是列表框或按钮。查看MSDN article on control authoring以获取有关如何执行此操作的一些建议。

答案 3 :(得分:0)

某些内容控件取决于ControlTemplate中是否存在其他控件。通常,应使用TemplatePart属性记录此内容。

例如,Combobox控件取决于其模板中是否存在TextBoxPopup控件。

这可以通过将属性放在类上来记录:

[TemplatePart(name="PART_EditableTextBox", type=typeof(TextBox))]
[TemplatePart(name="PART_Popup", type=typeof(Popup))]
public class Combobox : Selector
{
    [...]

命名约定是“PART_controlIdentifier”。

然后,控件模板中的相关项将被赋予相同的名称,以便它们可以位于OnApplyTemplate方法中。

然后,这允许控件在模板中包含的控件上连接事件,设置属性和调用方法。

此属性用于文档目的,以便设计自定义控件模板(以及Expression Blend等工具)的人知道控件依赖于另一个控件的存在。

答案 4 :(得分:0)

了解如何同时使用dependency propertiesrouted events(及其工作方式),以便您可以在自己的控制中有效地使用它们。

这两种类型都提供了将控件与WPF内置系统集成的服务。

通过在自定义控件中使用这两个功能,您将获得以下优势:

  1. 依赖项属性提供对数据绑定,动画的支持,可以在样式中使用。

  2. 路由事件可以通过可视树传播,这意味着其他元素可以处理事件。