65.9K
CodeProject 正在变化。 阅读更多。
Home

Silverlight:创建类似 UserControl 的自定义控件

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.89/5 (7投票s)

2008年11月7日

CPOL

2分钟阅读

viewsIcon

58357

downloadIcon

503

本文介绍了如何在 Silverlight 2.0 中创建一个对开发者友好的自定义控件。

引言

Silverlight 2.0 开发者可以通过以下方式添加控件:

  1. 直接在应用程序的 XAML 中复制控件的 XAML - 这种方式控件不可重用,开发者必须克隆代码以提供另一个控件
  2. 创建 UserControl - 但是 UserControl 是一个容器,是重量级控件
  3. 创建自定义控件 - 轻量级,更适合于重复使用

背景

Microsoft 官方创建自定义控件的方式是:创建 Silverlight 类库,将 *generic.xaml* 添加到项目中,创建一个继承自 Control 的类等等。一个简短的教程可以在这里找到。

由于所有的 XAML 都存储在 *generic.xaml* 中,这个文件会变得很大,而修改一个大文件是个问题。想象一下你有 10 个控件,并且想要将第一个控件的一个动画复制到最后一个控件中。滚动和定位代码会非常耗时。

如果自定义控件可以像 UserControl 那样创建 - 包含 XAML 文件和代码隐藏文件呢?开发者可以很容易地在这两部分之间切换。本文描述了一种组织自定义控件的技术。

分步指南

创建一个新的 UserControl 以获得 *.xaml* 和 代码隐藏 文件(*.cs*,*.vb*)。

选择 *.xaml* 并将 生成操作 更改为 Resource

打开 *.xaml* 文件并将 UserControl 标签 替换为 ResourceDictionary,同时移除 WidthHeightx:Class 属性。

打开 *.cs* 文件。将 UserControl 替换为 Control,从构造函数中移除 InitializeComponent();。添加 Loaded 事件处理程序,并调用 static 方法从 XAML 加载样式。

现在已经创建了一个自定义控件,但是它没有任何功能。为了使它有用,将 Style、Storyboards、视觉元素添加到 *.xaml* 中,并在 *.cs* 中创建重写的 OnApplyTemplate()。关于设计和编程自定义控件的文章可以在 The Code Project 或者在 互联网上找到。

Loader 类

此示例的 Loader 类包含 static LoadStyle(Control control) 方法。该方法从类型中获取控件名称,从资源中加载 XAML,并将样式应用于控件。

代码

public static void LoadStyle(Control control)
{
    try
    {
        int b;
        List<byte> bytes = new List<byte>();
        string name = control.GetType().Name;
        string assembly = "development";
        string directory = "Controls/";
        string path = string.Format(
            "/{0};component/{1}{2}.xaml",
            assembly, directory, name);

        //Read xaml as string
        StreamResourceInfo info = Application.GetResourceStream(
            new Uri(path, UriKind.Relative));
        while ((b = info.Stream.ReadByte()) >= 0)
        {
            bytes.Add((byte)b);
        }
        string xaml = Encoding.UTF8.GetString(
            bytes.ToArray(), 0, bytes.Count);

        //Create xaml object from string
        object obj = XamlReader.Load(xaml);
        if (obj != null && obj is ResourceDictionary)
        {
            string key = name + "Style";
            control.Style = (Style)((ResourceDictionary)obj)[key];
        }
    }
    catch
    {
    }
} 

兴趣点 

在 WPF 中,自定义控件样式可以在 ResourceDictionary.MergedDictionaries 中链接。Silverlight 还没有这个功能。

历史

  • 2008 年 11 月 7 日:初始发布
© . All rights reserved.