源文:http://www.cnblogs.com/bicker/p/3318934.html

最近接触C#的PropertyGrid比较多,得到了两个小心得记录一下。

第1点是关于控制PropertyGrid中属性的只读属性的。

我遇到的问题是这样的,我需要在运行时根据SVN的状态动态控制PropertyGrid中的属性的读写控制。以前的做法比较简单,直接是 PropertyGrid.Enabled(false)。这样的坏处是完全使Grid完全失效,连滚动条也不可用了,不便于查看属性。后来上网查阅相关 的资料,网上有比较的是同一篇文章的复制,原文出处我已经找不到了。先把原文贴出来如下:

大家知道在类的某个属性中加[ReadOnlyAttribute(true)]声明标记后,此类的对象的这个属性在PropertyGrid中就表现为灰色不可更改,请问大家有没有什么办法动态地让这个属性在PropertyGrid中的显示变为可读写么?   
  以下的方法试过,不好用   
  1、想在程序里改声明标记,可是不行   
  2、另外写个类,同样的属性标记为[ReadOnlyAttribute(false)],然后重新selectobject,可是太复杂了。

用反射可以实现动态改变,只读、可见等等,这些属性都可以改变。

以下两个方法分别实现可见性和只读属性的动态改变:

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);   
  }

使用时,SetPropertyVisibility(obj,   "名称",   true);   
  obj指的就是你的SelectObject,   “名称”是你SelectObject的一个属性   
  当然,调用这两个方法后,重新SelectObject一下,就可以了

心得:

(1)如果对属性框中所有属性一起进行控制,可以不添加 [ReadOnlyAttribute(false)]标记,propertyName可以是任何属性名称。[注:这里讲得很不清楚]

(2)如果仅仅对某一个属性进行控制,则必须在每个属性的描述中添加 [ReadOnlyAttribute(false)]标记。propertyName必须是所要控制的属性名。

原文中提到的思路是在运行时,通过反射的方式修改每一个Property的ReadOnlyAttribute。只是心得那里説不很不清楚,要对整个对象而非具体的属性进行控制时怎么办。

我的第一个想法是遍历所有的Property,对每一个都设置ReadOnly,但是这样是错误的,而且有副作用。后来经过试验,我直接对PropertyGrid的Object设置ReadOnly。

1 private void button1_Click(object sender, EventArgs e)
2 {
3 Type readonlyType = typeof(System.ComponentModel.ReadOnlyAttribute);
4 PropertyDescriptorCollection props = TypeDescriptor.GetProperties(propertyGrid1.SelectedObject);
5 FieldInfo fld = readonlyType.GetField("isReadOnly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.CreateInstance);
6 AttributeCollection attrs = TypeDescriptor.GetAttributes(propertyGrid1.SelectedObject);
7 fld.SetValue(attrs[typeof(ReadOnlyAttribute)], gridReadOnly);
8 gridReadOnly = !gridReadOnly;
9 }

这里説一下,在找解决办法的时候,还去顺便了解了一下c#在运行时,动态添加Attribute的内容,这个内容留下次再记录好了。

还找到一篇讲反射可以通过FieldInfo.SetValue设置任何字段的值的文章:http://www.cnblogs.com/Laser_Lu/archive/2004/08/01/29171.html

第2点是PropertyGrid中使用TypeConverter

PropertyGrid中对于自定义的类型显示支持有限,最好是自己去实现自己的TypeConverter,把类型转换来进行显示。我写了一个简单的例子,把List类型转换成string。

 1 public class MyColorConverter : TypeConverter
2 {
3 public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
4 {
5 if (value == null)
6 {
7 return new List<int>();
8 }
9 string stringValue = value as string;
10 if (stringValue != null)
11 {
12 List<int> result = new List<int>();
13 string[] vs = stringValue.Split(new char[] { ',' });
14 foreach (string eachString in vs)
15 {
16 result.Add(int.Parse(eachString));
17 }
18 return result;
19 }
20 else
21 {
22 return base.ConvertFrom(context, culture, value);
23 }
24 }
25
26 public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType)
27 {
28 if (destinationType == typeof(string))
29 {
30 return true;
31 }
32 return base.CanConvertTo(context, destinationType);
33 }
34
35 public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributes)
36 {
37 throw new Exception("The method or operation is not implemented.");
38 }
39
40 public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
41 {
42 if (destinationType == typeof(string))
43 {
44 List<int> list = value as List<int>;
45 if (list != null && list.Count > 0)
46 {
47 StringBuilder sb = new StringBuilder();
48 foreach (int v in list)
49 {
50 sb.AppendFormat("{0},", v);
51 }
52 sb.Remove(sb.Length - 1, 1);
53 return sb.ToString();
54 }
55 return "";
56 }
57 else
58 {
59 return base.ConvertTo(context, culture, value, destinationType);
60 }
61 }
62
63 public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
64 {
65 if (sourceType == typeof(string))
66 {
67 return true;
68 }
69 return base.CanConvertFrom(context, sourceType);
70 }
71 }
     private List<int> color1 = new List<int>();
[Category("main")]
[DisplayName("颜色1")]
[TypeConverter(typeof(MyColorConverter))]
public List<int> Color1
{
get { return color1; }
set { color1 = value; }
}

ConvertFrom函数会在PropertyGrid中的字符串被修改保存后被调用

ConvertTo函数则是在最初显示PropertyGrid以及对List进行修改之后被调用

两点C#的propertyGrid的使用心得【转】的更多相关文章

  1. 两点C#的propertyGrid的使用心得

    最近接触C#的PropertyGrid比较多,得到了两个小心得记录一下. 第1点是关于控制PropertyGrid中属性的只读属性的. 我遇到的问题是这样的,我需要在运行时根据SVN的状态动态控制Pr ...

  2. C# PropertyGrid控件应用心得

    何处使用 PropertyGrid 控件 在应用程序中的很多地方,您都可以使用户与 PropertyGrid 进行交互,从而获得更丰富的编辑体验.例如,某个应用程序包含多个用户可以设置的“设置”或选项 ...

  3. C# PropertyGrid控件应用心得 【转】

    源文 : http://blog.csdn.net/luyifeiniu/article/details/5426960 c#stringattributesobjectmicrosoftclass ...

  4. 关于CSS中float的两点心得以及清除浮动的总结

    对一个元素运用float后,该元素将脱离正常文档流,这意味着: 1. 运用float后,该元素不再影响父元素的高度,如果一个元素的所有子元素都是float的话,那么该元素的高度是0,这样后面元素渲染的 ...

  5. PropertyGrid控件由浅入深(二):基础用法

    目录 PropertyGrid控件由浅入深(一):文章大纲 PropertyGrid控件由浅入深(二):基础用法 控件的外观构成 控件的外观构成如下图所示: PropertyGrid控件包含以下几个要 ...

  6. C# 如何定义让PropertyGrid控件显示[...]按钮,并且点击后以下拉框形式显示自定义控件编辑属性值

    关于PropertyGrid控件的详细用法请参考文献: 1.C# PropertyGrid控件应用心得 2.C#自定义PropertyGrid属性 首先定义一个要在下拉框显示的控件: using Sy ...

  7. windows类书的学习心得(转载)

    原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...

  8. 百度api使用心得体会

    最近项目中在使用百度地图api,对于其中的一些有用的点做一些归纳整理,如有不对的地方,欢迎各位大神纠正指出. 一定要学会查找百度地图api提供的类参考网站:http://lbsyun.baidu.co ...

  9. System.Windows.Forms.PropertyGrid的使用

    PropertyGrid 控件简介 .NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心.PropertyGrid 控件显示对象或类型的属性,并主要 ...

随机推荐

  1. javascript常见数据集

    目录 数组 对象 一.数组 创建方法 1 2 3 var arrayObj = new Array(); //创建一个数组             var arrayObj = new Array([ ...

  2. 【Java学习笔记之九】java二维数组及其多维数组的内存应用拓展延伸

    多维数组声明 数据类型[][] 数组名称; 数据类型[] 数组名称[]; 数据类型数组名称[][]; 以上三种语法在声明二维数组时的功能是等价的.同理,声明三维数组时需要三对中括号,中括号的位置可以在 ...

  3. [python工具][1]sublime安装与配置

    http://www.cnblogs.com/wind128/p/4409422.html 1 官网下载版本  http://www.sublimetext.com/3 选择 Windows - al ...

  4. Spring 4.3.11.RELEASE文档阅读(二):Core Technologies_AOP

    虽然并不是每个问题都有答案,但我想了很多问题.so, just write it down , maybe one day...... AOP: 1,AOP是啥 2,AOP思想是怎么产生的 3,AOP ...

  5. BZOJ-1085 骑士精神

    估价函数其实就是与目标状态有几个不同... 迭代启发搜索. #include <cstdlib> #include <cstdio> #include <cstring& ...

  6. mybatis学习(十二)——mybatis逆向工程

    MyBatis Generator (MBG)是一个mabatis的代码生成器,能够根据表自动生成mapper接口,mapper.xml文件,javaBean文件. 1.MBG的下载 打开https: ...

  7. [HDU4362] Palindrome subsequence (区间DP)

    题目链接 题目大意 给你几个字符串 (1<len(s)<1000) ,要你求每个字符串的回文序列个数.对于10008取模. Solution 区间DP. 比较典型的例题. 状态定义: 令 ...

  8. 【CF739B】Alyona and a tree(树上差分,二分,树形DP)

    题意:给出一棵有根树,树上每个点.每条边都有一个权值. 现在给出“控制”的定义:对一个点u,设点v在其子树上,且dis(u,v)≤av,则称u控制v. 要求求出每个点控制了多少个点 n (1 ≤ n  ...

  9. 免费CSS鼠标样式代码大全

    原文发布时间为:2008-08-01 -- 来源于本人的百度文章 [由搬家工具导入] http://5211.91.tc/sb.htm

  10. windows命令行中java和javac、javap使用详解(java编译命令)

    如题,首先我们在桌面,开始->运行->键入cmd 回车,进入windows命令行.进入如图所示的画面: 可知,当前默认目录为C盘Users文件夹下的Administrator文件夹.一般而 ...