我试图弄清楚添加自定义UI的最佳方法是什么(我不想故意将其称为自定义控件)。我想创建一个自定义控件,但我真的不需要它来模板化。我想用其他控件直观地实现它。在我的示例中,我正在尝试创建一个控件,它使用Path对象来实现它。我希望它在创建时将Path控件“添加”到可视树。我希望它公开几个依赖项属性,我希望它在依赖项属性更改时更新Path对象。
我的第一种方法是从Control继承它,定义一个路径“Part”,在“OnApplyTemplate”例程中找到它,并在需要时更新它,但它似乎是一个巨大的矫枉过正。我现在实现的控件能够获得不同的控件模板,但它完全没用,因为函数必须在其中假设一个路径对象,并且它会覆盖此路径的大多数属性。它还暴露了许多我不需要的属性,如Background,BorderBrush,BorderThickness,所有这些我都不使用,而是根据我公开的其他属性进行计算。
所以问题是,我是否应该继承FrameworkElement,如果是这样,我如何“植入”我想要用来实现我的新自定义控件的Path对象?
答案 0 :(得分:0)
作为MSDN says:
直接从
FrameworkElement
派生并不常见,因为用于UI表示的类(例如模板支持)的某些预期服务未在该级别完全实现。...
FrameworkElement
提供了对许多基本方案的支持,但缺少许多功能,这些功能对于用于在XAML中创建UI的构建块意义上的“UI元素”而言是理想的。其中许多功能都是在Control
或FrameworkElement
的其他直接子类上实现的。
Silverlight库的反编译还表明你根本无法“绘制”FrameworkElement
中的任何内容,如果它的后代需要使用一个。 WPF中可能的功能在Silverlight中并不总是可行,尤其是在核心级别。
我会坚持Control
后代。我将TemplatePartAttribute
应用于类定义,以指定它需要一个Path
对象:
[TemplatePart(Name="ThePath", Type=typeof(Path))]
public class MyControl { ... }
然后在OnApplyTemplate
我会检查新模板是否有路径。这样,如果模板中有多个Path
,它就会知道要使用哪个Path
。
这种方法有一个显着的优点:如果有人(甚至你)想要在不改变逻辑的情况下向控件的视觉外观添加内容,则只需定义一个新模板即可完成。例如,使用框包装Path
的模板:
<ControlTemplate TargetType="MyControl">
<Border BorderThickness="{TemplateBinding Control.BorderThickness}"
BorderBrush="{TemplateBinding Control.BorderBrush}"
Background="{TemplateBinding Control.Background}">
<Path Name="ThePath" Stroke="{TemplateBinding Control.Foreground}"
StrokeThickness="1.5"/>
</Border>
</ControlTemplate>
对于公开的属性,尝试使用最相关的继承属性,至少是默认行为。