0

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

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

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

4

1 回答 1

0

正如MSDN 所说

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

...

FrameworkElement提供对许多基本方案的支持,但在用于在 XAML 中创建 UI 的构建块的意义上,缺少一些“UI 元素”所需的功能。许多这些特性是在Control. 或 . 的其他直接子类上实现的FrameworkElement

Silverlight 库的反编译还表明您根本无法在 a 中“绘制”任何内容FrameworkElement,如果它的后代,则需要使用它。WPF 中的可能在 Silverlight 中并不总是可能的,尤其是在核心级别。

我会坚持一个Control后代。我将 aTemplatePartAttribute应用于类定义以指定它需要有一个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>

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

于 2012-04-17T04:01:51.130 回答