- PropertyGrid只是一個控制項,要讓它像Form可以Show出來。
- 要有按鈕與User交互(Save, Save as, Accept, Close)
- 要能用選擇檔案(OpenFileDialog)/目錄(FolderBrowserDialog)的方式設定參數。
- 基本數值型別可以直接放到PropertyGrid顯示/修改,而自訂型別需要另外處理。
- 依照不同權限,在PropertyGrid中顯示不同的參數。
要能在PropertyGrid中選擇目錄和檔案(下兩圖),雖然FilePath和Folder都是字串型別而已,但總不能要使用者自己手打路徑吧,其實只要在參數上標示特性(Attribute)即可達成,相當容易,參考以下。
// 以FileNameEditor編輯字串,用來選檔案。 [EditorAttribute(typeof(System.Windows.Forms.Design.FileNameEditor) , typeof(System.Drawing.Design.UITypeEditor))] public string FilePath { get; set; }
// 以FolderNameEditor編輯字串,用來選目錄。 [EditorAttribute(typeof(System.Windows.Forms.Design.FolderNameEditor) , typeof(System.Drawing.Design.UITypeEditor))] public string Folder { get; set; }
在PropertyGrid中顯示自訂型別(如下圖),這部份比較麻煩一點,自訂類別要繼承ExpandableObjectConverter,然後override CanConvertTo、ConvertTo、CanConvertFrom三個方法,參考以下範例,自訂PointXYZ類別:
public class PointXYZ : ExpandableObjectConverter { public double X { set; get; } public double Y { set; get; } public double Z { set; get; } public PointXYZ() { X = 0; Y = 0; Z = 0; } public PointXYZ(double x , double y , double z) { X = x; Y = y; Z = z; } public override bool CanConvertTo(ITypeDescriptorContext context ,System.Type destinationType) { if (destinationType == typeof(PointXYZ)) return true; return base.CanConvertTo(context , destinationType); } public override object ConvertTo(ITypeDescriptorContext context , CultureInfo culture , object value , System.Type destinationType) { if (destinationType == typeof(System.String) && value is PointXYZ) { PointXYZ p = (PointXYZ)value; return "X:" + p.X + ",Y:" + p.Y + ",Z:" + p.Z; } return base.ConvertTo(context , culture , value , destinationType); } public override bool CanConvertFrom(ITypeDescriptorContext context , System.Type sourceType) { if (sourceType == typeof(string)) return true; return base.CanConvertFrom(context , sourceType); } }
最後在類別參數標示特性(Attribute) TypeConverterAttribute:
[TypeConverterAttribute(typeof(PointXYZ))] public PointXYZ SomePoint { get; set; }詳細作法可以參考MSDN的文章Getting the Most Out of the .NET Framework PropertyGrid Control 中Support for Custom Types章節。
回到依照權限顯示不同項目的功能上,首先要自訂一個特性PermissionsAttribute : Attribute,有需要依照權限隱藏的項目標示特性如下:
[Permissions(2)] public string Info { get; set; }在打開參數容器時,需要定義容器權限值,當容器權限小於參數定義的權限特性值時,該參數就會被隱藏,參考以下參數容器程式片段:
PropertyInfo[] piObj = inputObject.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach (var eachItem in piObj) { PermissionsAttribute attPermission = (PermissionsAttribute)Attribute.GetCustomAttribute(eachItem , typeof(PermissionsAttribute)); if (attPermission != null) { if (permission < attPermission.Value) { hiddenProperties.Add(eachItem.Name); } } } this.filteredPropertyGrid.SelectedObject = inputObject; this.filteredPropertyGrid.HiddenProperties = hiddenProperties.ToArray(); this.filteredPropertyGrid.Refresh();上述針對應用面的問題提出解法,並整合了許多網路資源來達到目標,除了本文提到的用法之外,在Getting the Most Out of the .NET Framework PropertyGrid Control文章中也有許多常用的用法,下篇文章將會以範例的方式介紹本文的程式用法。