我已经开始为高度可视化的项目编写一些自定义控件。我想知道在编写WPF自定义控件时你的“最佳实践”是什么?
答案 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
控件取决于其模板中是否存在TextBox
和Popup
控件。
这可以通过将属性放在类上来记录:
[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 properties和routed events(及其工作方式),以便您可以在自己的控制中有效地使用它们。
这两种类型都提供了将控件与WPF内置系统集成的服务。
通过在自定义控件中使用这两个功能,您将获得以下优势:
依赖项属性提供对数据绑定,动画的支持,可以在样式中使用。
路由事件可以通过可视树传播,这意味着其他元素可以处理事件。