17

如果我有一个我编写的用户控件(在 Silverlight 中),它使用 XAML 来定义它的外观,我该如何制作它的自定义版本?

即我有 MyControl.xaml & MyControl.xaml.cs

如果我想要一个“SpecializedControl”子类,我需要做什么?我假设我只是创建一个新的代码文件,然后从 MyControl 继承。但是如果我想改变基类的外观怎么办——那我该怎么办?

4

4 回答 4

8

我写了这篇文章,以为你在谈论 WPF,而不是 Silverlight,但是可能有足够的重叠来提供帮助,所以无论如何我都会发布它。

如果“更改基类的外观”是指“提供新模板”,那么您需要的可能是 CustomControl,而不是 UserControl。

完成此操作的最佳方法是遵循其他 Microsoft 控件设置的示例,例如 Button 或 ListBox:

  1. 创建一个直接派生自 Control(或任何最接近您的控件)的类。
  2. 如果需要向控件公开任何属性(例如按钮上的文本),请确保将它们正确定义为 DependencyProperties。
  3. 如此处所述,创建一个名为 Themes/generic.xaml 的 ResourceDictionary 并为您的类添加一个包含模板的样式(不要给样式一个键)。
  4. 对控件上需要从控件获取值的元素的任何属性使用 TemplateBindings。
  5. 如果您需要将任何事件处理程序附加到模板中的元素,请给它们一个唯一的名称。Microsoft 使用在这些名称前加上“PART_”前缀的约定,我认为为了保持一致性,这样做是一件好事,但这并不是严格要求的。
  6. 同样,如果您需要附加事件处理程序,请重载 OnApplyTemplate()。在此方法中,您应该分离任何旧的事件处理程序(我们当然不希望任何内存泄漏!),并查找具有您在模板中提供的名称的元素 - 当您找到它们时,根据需要附加事件处理程序.

这当然比简单地从 UserControl 派生要多得多,但是如果您希望能够完全重新模板化控件,就像您可以使用内置控件一样,这就是实现它的方法。

另一方面,如果您只想提供一定数量的有限自定义,例如更改背景,或将命令与某些用户操作相关联,那么最好的做法是公开 DependencyProperties,这样就可以在控件的样式中设置,或者在控件的实例上设置。

在您提到想要自定义继承控件的外观的情况下,过程非常相似:只需使用新模板为新控件添加默认样式;如果您需要添加更多事件处理程序,请绝对确定您调用了 base.OnApplyTemplate()。

于 2008-10-22T14:29:56.287 回答
5

我不知道,我喜欢只用简单的物体做事。这是一篇文章,描述了一种将 XAML 设计的控件滑出继承层次结构的简单方法,以便您可以使用 SimpleThingsLikeInheritance 而不是 MicrosoftStuffThatAlmostWorks 自定义外观和行为

http://gen5.info/q/2009/02/10/subverting-xaml-how-to-inherit-from-silverlight-user-controls/

于 2009-02-11T17:16:36.080 回答
5

正如 Mihnea 的链接所述,最简单的解决方案是在 XAML 中简单地添加一个命名空间:

C#

public class MyBase : UserControl
{
}

public class FirstUserControl : MyBase
{
...
}

XAML

<local:MyBase 
    x:Class="FirstUserControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="YourAssembly" ...>

    <!-- Sticking with UserControl instead of local:MyBase makes this clearer -->
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                ..
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

..Your XAML
</local:MyBase>
于 2010-06-24T13:35:29.873 回答
0

您可以使用上面链接中描述的包装器来解决此问题。但是你也可以使用策略模式来解决这个问题。

在这篇文章中,我将解释如何实现这两种方法。 http://www.lab101.be/2008/07/silverlight-usercontrol-inheritance/

于 2009-03-06T11:46:25.250 回答