标签:
在开发Winform程序中,PropertyGrid是一个常用的控件,在使用PropertyGrid的过程中,只需要将对应的对象实例赋给PropertyGrid的SelectedObject属性即可。当然,需要在对应的对象定义中添加相应的属性。
1 class Human 2 { 3 private int _age; 4 private string _name; 5 private Gender _gender; 6 7 [DisplayName("姓名"), 8 Browsable(true)] 9 public string Name 10 { 11 get { return _name; } 12 set { _name = value; } 13 } 14 [DisplayName("年龄"), 15 Browsable(true)] 16 public int Age 17 { 18 get { return _age; } 19 set { _age = value; } 20 } 21 22 [DisplayName("性别"), 23 Browsable(true), 24 ReadOnly(true)] 25 public Gender Gender 26 { 27 get { return _gender; } 28 set { _gender = value; } 29 } 30 31 } 32 33 enum Gender 34 { 35 Man, 36 Woman 37 }
可以看到,用户可以自定义属性在PropertyGrid中的显示,包括显示名称等等。注意代码中的ReadOnly特性以及Browsable特性,这两个特性的值在编译完成之后无法在更改。
但是我们可能有这样的需求,在程序运行过程中动态的更改ReadOnly特性以及Browsable特性。此时可以通过反射来实现,先上代码
1 public partial class Form1 : Form 2 { 3 Human _human = null; 4 public Form1() 5 { 6 InitializeComponent(); 7 _human = new Human { Name = "Jashon Han", Gender = Gender.Man, Age = 26 }; 8 Load += Form1_Load; 9 10 } 11 12 void Form1_Load(object sender, EventArgs e) 13 { 14 this.propertyGrid1.SelectedObject = _human; 15 } 16 17 private void buttonReadOnly_Click(object sender, EventArgs e) 18 { 19 SetPropertyReadOnly(_human,"Gender",true); 20 this.propertyGrid1.SelectedObject = _human; 21 } 22 23 private void buttonHide_Click(object sender, EventArgs e) 24 { 25 SetPropertyVisibility(_human,"Age",false); 26 this.propertyGrid1.SelectedObject = _human; 27 } 28 29 private void SetPropertyVisibility(object obj, string propertyName, bool visible) 30 { 31 try 32 { 33 Type type = typeof(BrowsableAttribute); 34 PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); 35 AttributeCollection attrs = props[propertyName].Attributes; 36 FieldInfo fld = type.GetField("browsable", BindingFlags.Instance | BindingFlags.NonPublic); 37 fld.SetValue(attrs[type], visible); 38 } 39 catch (Exception ex) 40 { 41 MessageBox.Show(ex.ToString()); 42 } 43 } 44 45 private void SetPropertyReadOnly(object obj, string propertyName, bool isReadOnly) 46 { 47 try 48 { 49 Type type = typeof(ReadOnlyAttribute); 50 PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj); 51 AttributeCollection attrs = props[propertyName].Attributes; 52 FieldInfo fld = type.GetField("isReadOnly", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.CreateInstance); 53 fld.SetValue(attrs[type], isReadOnly); 54 } 55 catch (Exception ex) 56 { 57 MessageBox.Show(ex.ToString()); 58 } 59 60 }
运行效果如下:
点击"性别为只读"按钮:
点击“隐藏年龄”按钮 :
标签:
原文地址:http://www.cnblogs.com/Jason-han/p/4467758.html