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

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

1
对于像这样的问题,您应该每个答案只询问一个提示/建议,以备将来参考。 - Bryan Anderson
5个回答

4
如果您想让您的自定义控件支持直接内容,如下所示:
<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 属性。

例如:

[ContentProperty("Text")]

该属性也不必是依赖属性(请参阅MSDN文档示例以证明此点)。

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


3

如果可能的话,请保持自定义控件属性名称与内置控件属性名称相同,而不改变其含义。

例如,如果您有一个名为CustomerDisplayer的自定义控件,请不要将客户列表称为“Customers”,而应该称为“ItemsSource”。

这可能会在一开始时看起来违反直觉,但从长远来看,它可以节省很多麻烦,因为未来的程序员可以对名为“ItemsSource”的属性做出许多假设,而对于“Customers”属性,他们不能必然地做出这些假设。


2

确保控件可以重新进行样式和模板的设计而不改变控件的操作方式。不要让控件假设Listbox和Button都在同一个面板中,或者根本不存在Listbox或Button。请参考MSDN有关控件编写的文章以获取一些如何实现此目标的建议。


1
一些内容控件依赖于其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等工具)的人知道该控件依赖于另一个控件的存在。


0

学习如何同时使用依赖属性路由事件(以及它们的工作原理),以便您可以在自己的控件中有效地使用它们。

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

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

  1. 依赖属性支持数据绑定、动画,并可用于样式。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接