- 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文章中也有許多常用的用法,下篇文章將會以範例的方式介紹本文的程式用法。