1. 只有public的property能顯示出來,可以通過BrowsableAttribute來控制是否顯示,通過CategoryAttribute設置分類,通過DescriptionAttribute設置描述,Attribute可以加在Class上,也可以加在屬性上,屬性上的Attribute優先級更高;
2. enum會自動使用列表框表示;
3. 自帶輸入有效性檢查,如int類型輸入double數值,會彈出提示對話框;
4. 基本類型Array:增加刪除只能通過彈出的集合編輯器,修改可以直接展開,值為null時,可以通過集合編輯器創建;
5. 基本類型List:增刪改都只能通過集合編輯器,值為null時,能打開集合編輯器,但不能保存結果,所以必須初始化;
6. ReadOnlyAttribute設置為true時,顯示為灰色;對List無效,可以打開集合編輯器,在集合編輯器內可以進行增刪改;應用於Array時,不能打開集合編輯器,即不能增刪,但可以通過展開的方式修改Array元素;
7. 對象:值顯示Object.ToString();Class上加了[TypeConverter(typeof(ExpandableObjectConverter))]之后(也可以加在屬性上),才能展開編輯,否則顯示為灰色只讀;不初始化什么也干不了;
8. 基類類型派生類對象:與普通對象沒有區別,[TypeConverter(typeof(ExpandableObjectConverter))]加在基類上即可;
9. 對象Array:增加刪除只能通過彈出的集合編輯器,修改可以直接展開,值為null時,可以通過集合編輯器創建;
10. 對象List:增加刪除修改只能通過彈出的集合編輯器,值為null時,能打開集合編輯器,但不能保存結果,所以必須初始化;
11. Hashtable和Dictionary能打開集合編輯器,但不能編輯;
12. 通過MyDoubleConverter實現Double類型只顯示小數點后兩位:
public class MyDoubleConverter : DoubleConverter { public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { return string.Format("{0:0.00}", value); } return base.ConvertTo(context, culture, value, destinationType); } }
13. 通過TypeConverter實現用字符串表示對象
[TypeConverter(typeof(StudentConverter))] public class Student { public Student(string name, int age) { Name = name; Age = age; } public string Name { get; set; } public int Age { get; set; } public static Student FromString(string s) { string name = "Default"; int age = 0; string[] splits = s.Split(','); if (splits.Length == 2) { name = splits[0]; int.TryParse(splits[1], out age); } return new Student(name, age); } public override string ToString() { return string.Format("{0},{1}", Name, Age); } } public class StudentConverter : TypeConverter { public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType) { if (sourceType == typeof(string)) { return true; } return base.CanConvertFrom(context, sourceType); } public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) { Student result = null; if ((value as string) != null) { result = Student.FromString(value as string); } return result; } public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(string)) { return true; } return base.CanConvertTo(context, destinationType); } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(string)) { return value.ToString(); } return base.ConvertTo(context, culture, value, destinationType); } }
14. 使用UITypeEditor實現文件或目錄選擇
// 需要在項目里添加引用:程序集|框架|System.Design [Editor(typeof(FileNameEditor), typeof(UITypeEditor))] public string FileName { get; set; } [Editor(typeof(FolderNameEditor), typeof(UITypeEditor))] public string FolderName { get; set; }
15. 使用自定義的下拉式編輯界面
public class MyAddress { public string Province { get; set; } public string City { get; set; } public override string ToString() { return string.Format("{0}-{1}", Province, City); } } public class MyAddressEditor : UITypeEditor { public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.DropDown; } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { IWindowsFormsEditorService service = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; if (service != null) { service.DropDownControl(new MyEditorControl(value as MyAddress)); } return value; } } // 實現兩個ComboBox用來編輯MyAddress的屬性 public partial class MyEditorControl : UserControl { private MyAddress _address; public MyEditorControl(MyAddress address) { InitializeComponent(); _address = address; comboBoxProvince.Text = _address.Province; comboBoxCity.Text = _address.City; } private void comboBoxProvince_SelectedIndexChanged(object sender, EventArgs e) { _address.Province = comboBoxProvince.Text; } private void comboBoxCity_SelectedIndexChanged(object sender, EventArgs e) { _address.City = comboBoxCity.Text; } } // MyAddress屬性聲明 [Editor(typeof(MyAddressEditor), typeof(UITypeEditor))] public MyAddress Address { get; set; }
效果如圖:

16. 實現彈出式編輯對話框,只要將UserControl改成Form,EditStyle改成Modal,service.DropDownControl改成service.ShowDialog
public partial class MyEditorForm : Form { private MyAddress _address; public MyEditorForm(MyAddress address) { InitializeComponent(); _address = address; comboBoxProvince.Text = _address.Province; comboBoxCity.Text = _address.City; } private void comboBoxProvince_SelectedIndexChanged(object sender, EventArgs e) { _address.Province = comboBoxProvince.Text; } private void comboBoxCity_SelectedIndexChanged(object sender, EventArgs e) { _address.City = comboBoxCity.Text; } } public class MyAddressEditor : UITypeEditor { public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context) { return UITypeEditorEditStyle.Modal; } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { IWindowsFormsEditorService service = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService; if (service != null) { service.ShowDialog(new MyEditorForm(value as MyAddress)); } return value; } }
17. 密碼表示:[PasswordPropertyText(true)]
18. 動態顯示/隱藏屬性
class MyData { public static void SetPropertyAttribute(object obj, string propertyName, Type attrType, string attrField, object value) { PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); Attribute attr = props[propertyName].Attributes[attrType]; FieldInfo field = attrType.GetField(attrField, BindingFlags.Instance | BindingFlags.NonPublic); field.SetValue(attr, value); } private bool _ShowPassword = false; public bool ShowPassword { get { return _ShowPassword; } set { _ShowPassword = value; SetPropertyAttribute(this, "Password", typeof(BrowsableAttribute), "browsable", _ShowPassword); } } [PasswordPropertyText(true)] [Browsable(true)] public string Password { get; set; } } public partial class MainFrm : Form { // 不添加PropertyValueChanged事件,不能實現動態顯示/隱藏 private void myData_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { this.myData.SelectedObject = this.myData.SelectedObject; } }
19. 提供下拉選項的string
public class ListStringConverter : StringConverter { public override bool GetStandardValuesSupported(ITypeDescriptorContext context) { return true; } public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { return new StandardValuesCollection(new string[] { "A", "B" }); } public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) { return false; } } [TypeConverter(typeof(ListStringConverter))] public string Name { get; set; }
