Silverlight智能表单(3)之XML存储
时间:2011-01-24 来源:无名菜鸟
我最初的想法是存储到xml文件中,OK,说一下我的大体构架,该构架挺失败的(至少我是这样认为),但是我也没有其他更好的想法了,如果哪天想到了,我就努力完成这个智能表单的程序。
1.工具栏中所有的控件全部存储到XML文件中,其中包括各个控件的默认值。(ps:包括该控件的全名(如:System.Windows.Controls.Button)以及AssemblyName(如:System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e),如果有了这两个字段的话就可以反射出该控件了。)
2.生成好的表单存储成XML。包括表单的一些属性,以及各个控件及属性。
问题1:
如果存储成Xml,我想到的最好的办法是序列化。
OK开代码:(所有的控件前面加了一个X)
[System.Xml.Serialization.XmlIncludeAttribute(typeof(XTextBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XTextBlock))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XButton))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XPasswordBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XCheckBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XRadioButton))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XComboBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XDatePicker))] public class XFrameworkElement : Bases.ViewModelBase { [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Height { get;set; } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Width { get;set; } //........意思下,省略。。。 [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string CtrlName { get; set; } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string TypeName{ get; set; } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string AssemblyName{ get; set; } }
如果你想忽略某个属性不进行序列化就使用[System.Xml.Serialization.XmlIgnore],XmlElementAttribute这个类中有很多属性如ElementName,如果不知道看msdn。因为不同的控件属性也不一样,所以就需要定义不同的类,继承方式和类库中的一致(但不一定相同),类头上的那个定制属性中的类都是XFrameworkElement 的子类。
对于ViewModelBase类我贴下代码:
//一看都知道是干什么的,不知道的百度或者谷歌下,你不知道肯定也有人不知道,一定会有人问的,也一定会有人答的。
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
问题2:
因为我设想的是要反射出来所有的控件,但是有点问题,因为像TypeName不是控件的属性,需要区分开来。我的办法依旧是反射,定义一个定制属性:
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
public class FromCtrlAttribute : Attribute{}
就这么简单,什么都没有,它的意思指明该属性和控件中的属性一致。
于是乎:
[FromCtrlAttribute]
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public double Height{get;set;}
[FromCtrlAttribute]
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public double Width{get;set;}
然后我的创建控件的方法就出来了:
protected virtual FrameworkElement CreateControl() { return CreateControl(this); } protected virtual FrameworkElement CreateControl(XFrameworkElement xControl) { Assembly assembly = Assembly.Load(AssemblyName); Type type = assembly.GetType(TypeName); if (type != null) { //m_Control定义:internal FrameworkElement m_Control; m_Control = Activator.CreateInstance(type) as FrameworkElement; PropertyInfo[] ctrlProperties = type.GetProperties(BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); PropertyInfo[] thisProperties = xControl.GetType().GetProperties(); foreach (var item in thisProperties) { if (item.GetCustomAttributes(typeof(FromCtrlAttribute), false).Length > 0) { //item.Name foreach (var property in ctrlProperties) { if (property.Name == item.Name) { property.SetValue(m_Control, item.GetValue(xControl, null), null); } } } } } return m_Control; }
于是该类中的控件就被反射出来了。ps:AssemblyName和TypeName的值从哪里来?看第一个标号1,所有的控件包括默认值,我已经定义在xml文件中。
问题3:
先上一个图看一下:
不用多介绍了,红色的为我们的画板,右侧是一个DataForm控件。对于Background,FontWeight等属性,DataForm无法识别,不能够生成下拉框。
继续反射,先贴代码,然后再动嘴皮子。
using System; using System.Reflection; using System.Windows; using System.Windows.Input; using System.Windows.Media; namespace DragDrop.Bases { public class EnumCommon { public static object GetActValue(Type type, string value) { object actValue = null; object[] attributes = type.GetCustomAttributes(false); foreach (var attr in attributes) { if (attr is SourceAttribute) { Type sourcetype = (attr as SourceAttribute).SourceType; PropertyInfo[] properties = sourcetype.GetProperties(); foreach (var property in properties) { if (property.Name.Equals(value)) { actValue = property.GetValue(null, null); return actValue; } } } } return actValue; } } [SourceAttribute(typeof(Colors))] public enum ColorEnum { Black, Blue, Brown, Cyan, DarkGray, Gray, Green, LightGray, Magenta, Orange, Purple, Red, Transparent, White, Yellow, } [SourceAttribute(typeof(Cursors))] public enum CursorEnum { Arrow, Eraser, Hand, IBeam, None, SizeNESW, SizeNS, SizeNWSE, SizeWE, Stylus, Wait, } [SourceAttribute(typeof(FontWeights))] public enum FontWeightEnum { Black, Bold, ExtraBlack, ExtraBold, ExtraLight, Light, Medium, Normal, SemiBold, Thin, } [AttributeUsage(AttributeTargets.Enum, Inherited = false, AllowMultiple = false)] public class SourceAttribute : Attribute { public SourceAttribute(Type sourceType) { SourceType = sourceType; } public Type SourceType { get; private set; } } }
1.以CursorEnum为例,控件中的定义为:
[FromCtrlAttribute]
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public Bases.CursorEnum Cursor{get;set;}
2.SourceAttribute该属性说明CursorEnum枚举中的成员来自于Cursors类。(注意观察Cursors,Colors等类public static Cursor Arrow{ get; }几乎都是这样定义的都有public和static)
3.GetActValue()该方法的使用如:m_Control.Cursor = (Cursor)Bases.EnumCommon.GetActValue(typeof(Bases.CursorEnum), value.ToString());
返回值为object类型,然后你强制转化为你所需要的类型即可。property.GetValue(null, null); 这个用法我也不太清楚,随手一用居然返回值就是我所需要的。
如此一来,一些乱七八糟的东西也能够在DataForm中编辑了,还有一点需要说明的是Cursor现在是一个枚举了,当然也可以序列化了,可谓一箭双雕。
4.看下这个属性
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string CtrlName;// { get; set; }
我把get和set去掉了,变成了一个字段。主要原因是字段不会在DataForm中进行编辑的(最下面有详细代码)
(就是给你一个表的名称,你要实现添加删除更新,以及各种限制),感觉有点类似,还有原因是现在表单都没有设计好,于是数据库的建立等等没有考虑。
过几天分享那个控件的代码。
----------------------------------------
先贴一下我未完成的代码,关于我的X控件的(没有完成):
[System.Xml.Serialization.XmlIncludeAttribute(typeof(XTextBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XTextBlock))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XButton))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XPasswordBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XCheckBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XRadioButton))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XComboBox))] [System.Xml.Serialization.XmlIncludeAttribute(typeof(XDatePicker))] public class XFrameworkElement : Bases.ViewModelBase { public XFrameworkElement() { Opacity = 1; Cursor = Bases.CursorEnum.Arrow; Height = 30; Width = 40; AssemblyName = "System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e"; } public XFrameworkElement(FrameworkElement control) : this() { Type ctrType = control.GetType(); TypeName = ctrType.FullName; AssemblyName = ctrType.Assembly.FullName; PropertyInfo[] ctrlProperties = ctrType.GetProperties(BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); PropertyInfo[] thisProperties = control.GetType().GetProperties(); foreach (var item in thisProperties) { if (item.GetCustomAttributes(typeof(FromCtrlAttribute), false).Length > 0) { //item.Name foreach (var property in ctrlProperties) { if (property.Name == item.Name) { item.SetValue(this, property.GetValue(control, null), null); } } } } } public XFrameworkElement(string type, string assembly) : this() { TypeName = type; AssemblyName = assembly; } #region Fileds private double m_Height; private double m_Width; private double m_Opacity; private string m_Name; private double m_Left; private double m_Top; private Bases.CursorEnum m_Cursor; #endregion #region Properties [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Height { get { return m_Height; } set { if (value < 0) { throw new Exception("不能小于0"); } if (m_Height != value) { m_Height = value; OnPropertyChanged("Height"); if (m_Control != null) { m_Control.Height = value; } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Width { get { return m_Width; } set { if (value < 0) { throw new Exception("不能小于0"); } if (m_Width != value) { m_Width = value; OnPropertyChanged("Width"); if (m_Control != null) { m_Control.Width = value; } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Opacity { get { return m_Opacity; } set { if (value < 0 || value > 1) { throw new Exception("介于0和1之间!"); } if (m_Opacity != value) { m_Opacity = value; OnPropertyChanged("Opacity"); if (m_Control != null) { m_Control.Opacity = value; } } } } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Name { get { return m_Name; } set { if (m_Name != value) { m_Name = value; OnPropertyChanged("Name"); if (m_Control != null) { m_Control.Name = value; } } } } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Left { get { return m_Left; } set { if (m_Left != value) { m_Left = value; OnPropertyChanged("Left"); if (m_Control != null) { Canvas.SetLeft(m_Control, value); } } } } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Top { get { return m_Top; } set { if (m_Top != value) { m_Top = value; OnPropertyChanged("Top"); if (m_Control != null) { Canvas.SetTop(m_Control, value); } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Bases.CursorEnum Cursor { get { return m_Cursor; } set { if (m_Cursor != value) { m_Cursor = value; OnPropertyChanged("Cursor"); if (m_Control != null) { m_Control.Cursor = (Cursor)Bases.EnumCommon.GetActValue(typeof(Bases.CursorEnum), value.ToString()); } } } } //Button [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string CtrlName;// { get; set; } //System.Windows.Controls.Button [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string TypeName; [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string AssemblyName; internal FrameworkElement m_Control; public FrameworkElement Control { get { if (m_Control == null) { CreateControl(); } return m_Control; } //private set { m_Control = value; } } #endregion protected virtual FrameworkElement CreateControl() { return CreateControl(this); } protected virtual FrameworkElement CreateControl(XFrameworkElement xControl) { Assembly assembly = Assembly.Load(AssemblyName); Type type = assembly.GetType(TypeName); if (type != null) { m_Control = Activator.CreateInstance(type) as FrameworkElement; PropertyInfo[] ctrlProperties = type.GetProperties(BindingFlags.Public | BindingFlags.GetProperty | BindingFlags.SetProperty); PropertyInfo[] thisProperties = xControl.GetType().GetProperties(); foreach (var item in thisProperties) { if (item.GetCustomAttributes(typeof(FromCtrlAttribute), false).Length > 0) { //item.Name foreach (var property in ctrlProperties) { if (property.Name == item.Name) { property.SetValue(m_Control, item.GetValue(xControl, null), null); } } } } m_Control.Tag = xControl; } return m_Control; } } public class XControl : XFrameworkElement { private Bases.ColorEnum m_Background; private Bases.ColorEnum m_Foreground; private double m_FontSize; private Bases.FontWeightEnum m_FontWeight; private bool m_IsEnabled; [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Bases.ColorEnum Background { get { return m_Background; } set { if (m_Background != value) { m_Background = value; OnPropertyChanged("Background"); if (m_Control != null) { (m_Control as Control).Background = new SolidColorBrush((Color)Bases.EnumCommon.GetActValue(typeof(Bases.ColorEnum), value.ToString())); } } } } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Bases.ColorEnum Foreground { get { return m_Foreground; } set { if (m_Foreground != value) { m_Foreground = value; OnPropertyChanged("Foreground"); if (m_Control != null) { (m_Control as Control).Foreground = new SolidColorBrush((Color)Bases.EnumCommon.GetActValue(typeof(Bases.ColorEnum), value.ToString())); } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double FontSize { get { return m_FontSize; } set { if (value <= 0) { throw new Exception("大于0"); } if (m_FontSize != value) { m_FontSize = value; OnPropertyChanged("FontSize"); if (m_Control != null) { (m_Control as Control).FontSize = value; } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Bases.FontWeightEnum FontWeight { get { return m_FontWeight; } set { if (m_FontWeight != value) { m_FontWeight = value; OnPropertyChanged("FontWeight"); if (m_Control != null) { (m_Control as Control).FontWeight = (FontWeight)Bases.EnumCommon.GetActValue(typeof(Bases.FontWeightEnum), value.ToString()); } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public bool IsEnabled { get { return m_IsEnabled; } set { if (m_IsEnabled != value) { m_IsEnabled = value; OnPropertyChanged("IsEnabled"); if (m_Control != null) { (m_Control as Control).IsEnabled = value; } } } } public XControl() : base() { m_IsEnabled = true; } public XControl(string type, string assembly) : base(type, assembly) { } public XControl(Control control) : base(control) { } } public class XTextBox : XControl { private string m_Text; private TextWrapping m_TextWrapping; private bool m_AcceptsReturn; private bool m_IsReadOnly; [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Text { get { return m_Text; } set { if (m_Text != value) { m_Text = value; OnPropertyChanged("Text"); if (m_Control != null) { (m_Control as TextBox).Text = value; } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public TextWrapping TextWrapping { get { return m_TextWrapping; } set { if (m_TextWrapping != value) { m_TextWrapping = value; OnPropertyChanged("TextWrapping"); (m_Control as TextBox).TextWrapping = value; } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public bool AcceptsReturn { get { return m_AcceptsReturn; } set { if (m_AcceptsReturn != value) { m_AcceptsReturn = value; OnPropertyChanged("AcceptsReturn"); (m_Control as TextBox).AcceptsReturn = value; } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public bool IsReadOnly { get { return m_IsReadOnly; } set { if (m_IsReadOnly != value) { m_IsReadOnly = value; OnPropertyChanged("IsReadOnly"); (m_Control as TextBox).IsReadOnly = value; } } } public XTextBox() : base() { } public XTextBox(string type, string assembly) : base(type, assembly) { } public XTextBox(TextBox control) : base(control) { } } public class XTextBlock : XFrameworkElement { private string m_Text; private TextWrapping m_TextWrapping; private TextTrimming m_TextTrimming; private Bases.ColorEnum m_Background; private Bases.ColorEnum m_Foreground; private double m_FontSize; private Bases.FontWeightEnum m_FontWeight; [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Bases.ColorEnum Foreground { get { return m_Foreground; } set { if (m_Foreground != value) { m_Foreground = value; OnPropertyChanged("Foreground"); if (m_Control != null) { (m_Control as TextBlock).Foreground = new SolidColorBrush((Color)Bases.EnumCommon.GetActValue(typeof(Bases.ColorEnum), value.ToString())); } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Text { get { return m_Text; } set { if (m_Text != value) { m_Text = value; OnPropertyChanged("Text"); (m_Control as TextBlock).Text = value; } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public TextTrimming TextTrimming { get { return m_TextTrimming; } set { if (m_TextTrimming != value) { m_TextTrimming = value; OnPropertyChanged("TextTrimming"); (m_Control as TextBlock).TextTrimming = value; } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public TextWrapping TextWrapping { get { return m_TextWrapping; } set { if (m_TextWrapping != value) { m_TextWrapping = value; OnPropertyChanged("TextWrapping"); (m_Control as TextBlock).TextWrapping = value; } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double FontSize { get { return m_FontSize; } set { if (value <= 0) { throw new Exception("大于0"); } if (m_FontSize != value) { m_FontSize = value; OnPropertyChanged("FontSize"); if (m_Control != null) { (m_Control as TextBlock).FontSize = value; } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Bases.FontWeightEnum FontWeight { get { return m_FontWeight; } set { if (m_FontWeight != value) { m_FontWeight = value; OnPropertyChanged("FontWeight"); if (m_Control != null) { (m_Control as TextBlock).FontWeight = (FontWeight)Bases.EnumCommon.GetActValue(typeof(Bases.FontWeightEnum), value.ToString()); } } } } public XTextBlock() : base() { } public XTextBlock(string type, string assembly) : base(type, assembly) { } public XTextBlock(FrameworkElement control) : base(control) { } } public class XButton : XControl { private string m_Content; [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Content { get { return m_Content; } set { if (m_Content != value) { m_Content = value; OnPropertyChanged("Content"); if (m_Control != null) { (m_Control as Button).Content = value; } } } } public XButton() : base() { } public XButton(string type, string assembly) : base(type, assembly) { } public XButton(Button control) : base(control) { } } public class XPasswordBox : XControl { [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Password { get; set; } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Char PasswordChar { get; set; } public XPasswordBox() : base() { } public XPasswordBox(string type, string assembly) : base(type, assembly) { } public XPasswordBox(PasswordBox control) : base(control) { } } public class XCheckBox : XControl { [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public bool IsChecked { get; set; } private string m_Content; [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Content { get { return m_Content; } set { if (m_Content != value) { m_Content = value; OnPropertyChanged("Content"); if (m_Control != null) { (m_Control as Button).Content = value; } } } } public XCheckBox() : base() { } public XCheckBox(string type, string assembly) : base(type, assembly) { } public XCheckBox(CheckBox control) : base(control) { } } public class XRadioButton : XControl { [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public bool IsChecked { get; set; } private string m_Content; [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Content { get { return m_Content; } set { if (m_Content != value) { m_Content = value; OnPropertyChanged("Content"); if (m_Control != null) { (m_Control as Button).Content = value; } } } } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string GroupName { get; set; } public XRadioButton() : base() { } public XRadioButton(string type, string assembly) : base(type, assembly) { } public XRadioButton(RadioButton control) : base(control) { } } public class XComboBox : XControl { public XComboBox() : base() { } public XComboBox(string type, string assembly) : base(type, assembly) { } } public class XDatePicker : XControl { [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public DatePickerFormat SelectedDateFormat { get; set; } [FromCtrlAttribute] [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public string Text { get; set; } public XDatePicker() : base() { } public XDatePicker(string type, string assembly) : base(type, assembly) { } public XDatePicker(ComboBox control) : base(control) { } } public class XForm : Bases.ViewModelBase { private double m_Height; private double m_Width; [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Height { get { return m_Height; } set { if (value < 0) { throw new Exception("不能小于0"); } if (m_Height != value) { m_Height = value; OnPropertyChanged("Height"); } } } [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public double Width { get { return m_Width; } set { if (value < 0) { throw new Exception("不能小于0"); } if (m_Width != value) { m_Width = value; OnPropertyChanged("Width"); } } } public ObservableCollection<XFrameworkElement> XFrameworkElements { get; set; } public XForm() { XFrameworkElements = new ObservableCollection<XFrameworkElement>(); } } [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)] public class FromCtrlAttribute : Attribute { }