問題:如下,我定義了一個對象,默認設置屬性WindowSize ,WindowSize 為不可見,通過改變SaveOnClose的值,動態的改變不可見的屬性的顯示和隱藏。
[DefaultPropertyAttribute("SaveOnClose")] public class AppSettings{ private bool saveOnClose = false; private Size windowSize = new Size(100,100); private Font windowFont = new Font("宋體", 9, FontStyle.Regular); [CategoryAttribute("文檔設置"), DefaultValueAttribute(true)] public bool SaveOnClose { get { return saveOnClose; } set { saveOnClose = value;} } [CategoryAttribute("文檔設置"), Browsable(false)] public Size WindowSize { get { return windowSize; } set { windowSize = value;} } [CategoryAttribute("文檔設置"), Browsable(false),] public Font WindowFont { get {return windowFont; } set { windowFont = value;} } }
那么,現在,既然有屬性的特性Browsable,可以設置屬性的顯示和隱藏,我們就可以通過改變這個參數的值,從而達到我們想要的效果。如下:
void SetPropertyVisibility(object obj, string propertyName, bool visible) { Type type = typeof(BrowsableAttribute); PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); AttributeCollection attrs = props[propertyName].Attributes; FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic); fld.SetValue(attrs[type], visible); } void SetPropertyReadOnly(object obj, string propertyName, bool readOnly) { Type type = typeof(System.ComponentModel.ReadOnlyAttribute); PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); AttributeCollection attrs = props[propertyName].Attributes; FieldInfo fld = type.GetField("isReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance); fld.SetValue(attrs[type], readOnly); }
以上方法,不用我說。一看就知道用途了吧,通過如下方法去調用:
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) { var item = propertyGrid1.SelectedObject; bool b = (bool)e.ChangedItem.Value; if (b) { SetPropertyVisibility(item, "WindowSize", b);//WindowSize必須是自定義屬性中的屬性名,如下也是 SetPropertyVisibility(item, "WindowFont", b); //SetPropertyReadOnly(item, "WindowFont", b); } else { SetPropertyVisibility(item, "WindowSize", b); SetPropertyVisibility(item, "WindowFont", b); //SetPropertyReadOnly(item, "WindowFont", b); } propertyGrid1.SelectedObject = item; }
通過以上方法就可以達到效果了。 需要注意幾點:
1.SetPropertyVisibility方法,SetPropertyReadOnly方法中的參數分別指:(item,’自定義屬性對象中的某個屬性名‘,值)
2.上述方法調用完后,記得需要再次 propertyGrid1.SelectedObject = item; 否則,是沒有效果的
參考文獻:http://bbs.csdn.net/topics/350150747