答案:使用WMFL实现可配置Windows窗体
作者: Joe Stegman
翻译:秋枫
原文出处:http://windowsforms.net/articles/wfml.aspx
文章原名: Using the Windows Forms XML Parser Sample
代码下载:下载
Introduction
这里介绍的是个带有可以扩展机制的例子,通过添加一个标记模型来实现。我们把里面的解析规则可以概述为“XML 元素映射到.NET Framework 类型 而XML 中的属性映射到类型的属性、方法(或者事件)”。这个例子包含一个markup parser通过解析XML文件来动态的产生一个对象的实例树。对于标记的格式包括下面的结构:
1. XML 命名空间 到 .NET Framework 命名空间的映射
2. 对象实例化名称
3. 对象验证及引用
4. 属性设置
5. 实例和静态方法
6. 事件委托
7. 组件引用
Disclaimer
这个例子中使用的技术不是下一版本Windows Forms的一部分。另外,这里的例子是针对.NET Framework version 1.1的,至于其他版本没有测试过。
Basic Sample
下面的例子显示了一个XML的语法用来声明或定义一个包含了Label的简单窗体。
xml version="1.0" encoding="utf-8" ?>
mapping xmlns="http://www.microsoft.com/2003/WindowsForms"
namespace="System.Windows.Forms;System.Drawing"?>
<wfml xmlns="http://www.microsoft.com/2003/WindowsForms"
xmlns:wfml="http://www.microsoft.com/2003/WFML">
<Form wfml:root="true" Text="Basic Sample" Size="300,200">
<Label Text="Hello World" AutoSize="True" Location="10, 20"/>
<method.Show/>
Form>
wfml>
WMFL解析器根据上面的XML文件来动态的生成一个窗体。这里假设上面的XML文件内容包含在“basic.xml”文件中。
MarkupParser parser = new MarkupParser();
object form = parser.Parse("basic.xml");
下面是动态生成的窗体:
Dissecting the Basic Sample
根据Xml文档中的定义,解析器进行了精确的处理,一个根标签,实体声明和一个结束标签。下面是对各部分的描述。
XML Declaration
xml version="1.0" encoding="utf-8" ?>
这行定义了XML针对这个例子的默认命名空间同时定义了元素和属性的前缀。
Instance Declarations
<Form wfml:root="true" Text="Basic Sample" Size="300,200">
<Label Text="Hello World" AutoSize="True" Location="10,20"/>
<method.Show/>
Form>
当处理xml的时候,解析器将通过默认构造函数创建一个窗体的实例,同时设置Text属性为“Basic Sample”,Size属性为“300,200”。解析器还创建了一个Label实例添加到窗体的Controls集合,同时设置了Label的Text属性为“Hello World”,设置他的AutoSize属性为“True”,Location属性为“10,20”。最后,解析器还调用了Show方法来显示窗体的实例。
XML Namespace to .NET Framework Mappings
解析器通过 标签来创建System.Windows.Forms.Form类的一个实例。.NET Framework 1.1版本至少包含两个不同的“Form”类型:一个是在System.Windows.Forms命名空间,另一个是在System.Web.UI.MobileControls。解析器通过Xml文件中的命名空间映射来选择需要创建的实例的命名空间,在这个例子中,元素使用默认的命名空间。而这里默认的为http://www.microsoft.com/2003/WindowsForms:
<wfml xmlns="http://www.microsoft.com/2003/WindowsForms" …
这里的“映射”就是指示Xml namespace到System.Windows.Forms .NET Framework 命名空间:
mapping xmlns="http://www.microsoft.com/2003/WindowsForms"
namespace="System.Windows.Forms;System.Drawing"?>
解析器通过这个映射来选择Form的类型命名空间为System.Windows.Forms而不是System.Web.UI.MobileControls”.
Collection Heuristics
当解析器遇到元素的子元素时,就会根据上面定义的映射规则来生成相对应的类的实例加入到父控件的一个容器(如果父控件是一个容器,就直接添加)。在默认的情况下,解析器寻找一个“Controls”集合但是也可以把子控件通过“.”符号加载到的不同的集合。
<MenuItem Text="New" >
<property.MenuItems>
<MenuItem Text="Window" Shortcut="CtrlN" />
<MenuItem Text="-" />
<MenuItem Text="Message" />
<MenuItem Text="Post" />
<MenuItem Text="Contact" />
<MenuItem Text="Internet Call" />
property.MenuItems>
MenuItem>
在上面的例子中,那些子菜单被明确的加入到父一级的MenuItem的“MenuItems”集合中。对于“property.PropertyName”符号在下面的Markup reference一节中会有更多的详细说明。
Markup Reference
这个简单的解析器使用一些的属性,元素和一些其他符号指令来处理转换。那些属性和元素在http://www.microsoft.com/2003/WFML命名空间下,同时使用“wfml”作为前缀。
wfml:ID Attribute
这个ID属性用来唯一表示元素的实例。另外,解析器还提供一个API通过ID来查询一个实例,在下面的例子中,Form元素被给了“form1”。
xml version="1.0" encoding="utf-8" ?>
mapping xmlns="http://www.microsoft.com/2003/WindowsForms"
namespace="System.Windows.Forms;System.Drawing"?>
<wfml xmlns="http://www.microsoft.com/2003/WindowsForms"
xmlns:wfml="http://www.microsoft.com/2003/WFML">
<Form wfml:ID="form1" Text="Basic Sample" Size="300,200">
<Label Text="Hello World" AutoSize="True" Location="10, 20"/>
<method.Show/>
Form>
wfml>
解析器能通过“Find”方法来重新获取“form1”实例。
MarkupParser parser = new MarkupParser();
Parser.Parse(“basic.xml”);
Form form1 =(Form)parser.Find(“form1”);
wfml:root Attribute
root属性标识由解析器的“Parser”方法生成的实例。整个Xml只能有一个元素使用root属性。下面的例子中“form1”元素包含了“root”属性。
xml version="1.0" encoding="utf-8" ?>
mapping xmlns="http://www.microsoft.com/2003/WindowsForms"
namespace="System.Windows.Forms;System.Drawing"?>
<wfml xmlns="http://www.microsoft.com/2003/WindowsForms"
xmlns:wfml="http://www.microsoft.com/2003/WFML">
<Form wfml:ID="form1" wfml:root="true" Text="Basic Sample" Size="300,200">
<Label Text="Hello World" AutoSize="True" Location="10, 20"/>
<method.Show/>
Form>
wfml>
下面是“Parse”方法返回一个“form1”实例:
MarkupParser parser = new Markupparser();
Form form1 = (Form)parser.Parse(“basic.xml”);
wfml:argument Attribute
当实例化类型的时侯,解析器使用类型的默认构造函数。但是有些类型没有默认的构造函数,比如Bitmap。
Argument属性专门为没有默认构造函数的类型传递一个参数。下面的例子就是为Bitmap的构造函数传递一个“c:\image.jpg”参数。
<Form wfml:root="true" wfml:ID="form1" Name="Form1" Text="Set Background">
<property.BackgroundImage>
<Bitmap wfml:argument="C:\\image.jpg"/>
property.BackgroundImage>
<method.Show/>
Form>
注意这里如果是使用带多个参数的构造函数是不可能的。
property Element
解析器的通常规则是xml元素映射到类型而xml属性映射到类型的属性。
<Element Attribute="string value"/>
解析器能通过TypeConverters(System.ComponentModel.TypeConverter)来有效的处理字符串到非字符串属性的转换。举例Form类的BackColor属性是“System.Drawing.Color”类型的,但是可以使用下面的设置:
<Form BackColor="Green"/>
在上面的例子中,BackColor属性是通过一个TypeConverter来把“Green”字符串转换成“System.Drawing.Color”得到的。在一般情况下TypeCoverter
上一个:如何获得 Windows 操作系统的版本
下一个:windows应用程序版的google搜索引擎源码