Silverlight自定义对象不是从Control继承的

时间:2012-04-16 16:10:42

标签: silverlight templates

我试图弄清楚添加自定义UI的最佳方法是什么(我不想故意将其称为自定义控件)。我想创建一个自定义控件,但我真的不需要它来模板化。我想用其他控件直观地实现它。在我的示例中,我正在尝试创建一个控件,它使用Path对象来实现它。我希望它在创建时将Path控件“添加”到可视树。我希望它公开几个依赖项属性,我希望它在依赖项属性更改时更新Path对象。

我的第一种方法是从Control继承它,定义一个路径“Part”,在“OnApplyTemplate”例程中找到它,并在需要时更新它,但它似乎是一个巨大的矫枉过正。我现在实现的控件能够获得不同的控件模板,但它完全没用,因为函数必须在其中假设一个路径对象,并且它会覆盖此路径的大多数属性。它还暴露了许多我不需要的属性,如Background,BorderBrush,BorderThickness,所有这些我都不使用,而是根据我公开的其他属性进行计算。

所以问题是,我是否应该继承FrameworkElement,如果是这样,我如何“植入”我想要用来实现我的新自定义控件的Path对象?

1 个答案:

答案 0 :(得分:0)

作为MSDN says

  

直接从FrameworkElement派生并不常见,因为用于UI表示的类(例如模板支持)的某些预期服务未在该级别完全实现。

     

...

     

FrameworkElement提供了对许多基本方案的支持,但缺少许多功能,这些功能对于用于在XAML中创建UI的构建块意义上的“UI元素”而言是理想的。其中许多功能都是在ControlFrameworkElement的其他直接子类上实现的。

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>

对于公开的属性,尝试使用最相关的继承属性,至少是默认行为。