【问题标题】:How to correctly inherit from a usercontrol defined in XAML in Silverlight如何正确继承 Silverlight 中 XAML 中定义的用户控件
【发布时间】:2008-10-22 14:07:19
【问题描述】:

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

即我有 MyControl.xaml 和 MyControl.xaml.cs

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

【问题讨论】:

  • 在您的问题正文中说一些关于 Silverlight 的内容可能是明智的。假设您在谈论 WPF,然后我才意识到您在询问 Silverlight,并且我不知道两者之间有多少交叉。
  • 在 XAML / UserControls 方面相当多。无论如何发布您的答案,它可能会有所帮助:)

标签: xaml inheritance user-controls silverlight-2.0


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      正如 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>
      

      【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 2013-09-03
        • 2018-12-21
        • 2010-12-02
        • 1970-01-01
        • 2011-01-16
        • 1970-01-01
        • 2011-08-25
        • 1970-01-01
        • 2010-11-18
        相关资源
        最近更新 更多