【问题标题】:Silverlight Custom object not inherited from ControlSilverlight 自定义对象未从 Control 继承
【发布时间】:2012-04-16 16:10:42
【问题描述】:

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

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

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

【问题讨论】:

    标签: silverlight templates


    【解决方案1】:

    作为MSDN says:

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

    ...

    FrameworkElement 提供了对许多基本方案的支持,但也缺少一些“UI 元素”所需的功能,这些功能在您用于在 XAML 中创建 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>
    

    对于暴露的属性,尽量使用最相关的继承属性,至少默认行为。

    【讨论】:

    • 谢谢帕维尔,我会接受你的推荐。问题是我正在编写的控件需要路径没有笔画,不使用前景色或背景色,实际上不需要模板化,所以使用 Control 对象作为基类,虽然它可能是唯一的方法,是一个巨大的矫枉过正......但是,正如你所说,在 Silverlight 中没有其他方法......
    • @KobiHari 我应该注意这是一个很奇怪的案例。但也许你最好使用另一个基类。也许形状?虽然我从来没有从那个类派生。
    • Shape 似乎是最好的派生类,除了我不知道如何渲染它...在 WPF 中我会扩展几何,然后扩展形状并使用我的新几何,但是这个在 Silverlight 中是不可能的。它可以从其他基类继承,但我不知道一旦我这样做了如何修改可视化树......开始认为这可能根本不可能。
    • @KobiHari 啊,没办法。似乎所有Shapes 都是用本机代码实现的。例如,Path 类唯一拥有的是一个“核心”依赖属性Data,代码为10533U。这意味着它只是本机实现的托管包装器。抱歉,这行不通。
    猜你喜欢
    • 2011-06-25
    • 2016-09-11
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 2015-06-20
    • 2012-12-17
    • 1970-01-01
    • 2019-09-19
    相关资源
    最近更新 更多