本文旨在帮助那些正在从WinForms转向Silverlight开发的开发者,使他们能够更轻松地进行过渡。假设读者已经对Silverlight应用程序的开发有了基本的了解,并且现在开始编写代码。
下载的文件是使用Microsoft Visual Web Developer 2010 Express创建的,目标是Silverlight 4。如果没有VS 2010并且正在使用VS 2008(带有Silverlight 3 SDK),应该能够将HierarchyNode或HierarchyTree文件复制到Silverlight项目中。
在寻找一个免费的Silverlight层次结构控件,但只找到了第三方控件,这些控件都需要付费。因此,在创建了这个控件之后,决定将其发布给社区,并且同时写一篇文章,强调WinForms开发者在转向Silverlight时遇到的一些问题。
一旦将控件引用或添加到项目中,该控件的行为就类似于大多数控件。可以在HierarchyTree中显示任何控件。控件必须继承自FrameworkElement(所有Silverlight控件和UserControl都继承自FrameworkElement)。所有控件应该是相同的类型和大小。
在显示树之前,需要使用HierarchyNode类的实例创建节点结构。HierarchyNode有一个Control属性,它处理希望在HierarchyTree中显示的控件的引用。它还有一个Children属性,允许向父节点添加子HierarchyNodes。通过使用这个类,将能够创建一个类似于熟知的TreeView控件的层次结构。HierarchyTree有三个值得注意的属性:
MyHierarchyTree.Items.Clear();
HierarchyNode JohnNode = CreateNode("John");
HierarchyNode JoeNode = CreateNode("Joe");
HierarchyNode ZaneNode = CreateNode("Zane");
HierarchyNode HugoNode = CreateNode("Hugo");
JohnNode.Children.Add(JoeNode);
JohnNode.Children.Add(ZaneNode);
JohnNode.Children.Add(HugoNode);
MyHierarchyTree.Nodes.Add(JohnNode);
MyHierarchyTree.Display();
从Winforms的角度来看,创建UserControl的基本步骤是相似的。然而,在构建Silverlight控件时,需要解决一些设计问题。
更改控件的命名空间并不像最初想象的那么简单。在代码后面的类中更改命名空间将导致InitializeComponent方法抛出异常。这是因为项目中有多个引用,尤其是XAML代码。因此,使用“查找和替换”来更改命名空间。不要全部替换。找到下一个并只替换适当的命名空间。这不仅会避免陷入困境,而且会让更好地理解Silverlight项目的构建方式。
属性也以不同的方式处理,使用DependencyProperty.Register方法。
public static DependencyProperty ChildSpacingProperty =
DependencyProperty.Register(
"ChildSpacing",
typeof(double),
typeof(HierarchyTree),
new PropertyMetadata(20d));
已经可以在互联网上找到大量关于DependencyProperty的信息。因此,这里没有必要详细介绍,只是要说,尽管有些人抱怨需要编写额外的代码,但有一些优势。DependencyProperty可以设置默认值并引发更改事件。
Silverlight控件中的属性默认在属性窗口中可见。.NET 4.0 Framework不再支持BrowsableAttribute。所以,尽管这不是Silverlight特有的,但值得注意的是,希望从属性窗口中隐藏的属性需要用EditorBrowsableAttribute进行装饰。
[EditorBrowsable(EditorBrowsableState.Never)]
System.Windows.Shapes替换了Winforms中的Systems.Drawing类。这是因为Silverlight基于XAML。好消息是System.Windows.Shapes直观且易于使用。实际上,如果习惯使用GDI+,会发现System.Windows.Shapes类非常有趣。许多类在工具箱中显示,所以只需要在设计器中拖放几个就可以感受到如何使用这些类。只是要小心,设计器并不总是在XAML中正确描述形状,所以如果它的行为不如预期,可以在网上查找其他示例。