源文: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. HDU 1533 二分图最小权匹配 Going Home

    带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配. 最后再把答案取一下反即可. #include <iostream> #include <cst ...

  2. loj2256 「SNOI2017」英雄联盟

    真的是裸背包啊-- #include <iostream> #include <cstdio> using namespace std; typedef long long l ...

  3. tornado中文教程

    http://docs.pythontab.com/tornado/introduction-to-tornado/ch2.html#ch2-1 python的各种库的中文教程 http://docs ...

  4. javascript学习笔记 - 引用类型 Function

    五 Function类型 每个函数都时Function类型的实例.函数也是对象. 声明函数: function func_name () {} //javascript解析器会在程序执行时率先读取函数 ...

  5. list 类

    题外:len = sizeof(a)/sizeof(a[0]); 求出数组长度 1.list是一种以双向链表方式实现的一种顺序容器.list容器中,存放元素的存储单元可以是连续的也可以是不连续的. 2 ...

  6. 九度oj 题目1455:珍惜现在,感恩生活

    题目描述: 为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品,其价格不等,并且只能整袋购买.请问:你用有限的资金最 ...

  7. 关于php ‘==’ 与 '===' 遇见的坑

    两个的区别所有PHPer都知道, 今天在遍历 xmlNode时,自己写的代码就碰坑了 想遍历xmlNode为数组 得到的xmlNode为 想要把所有的simpleXmlElement对象都遍历转成数组 ...

  8. java8新特性lamda表达式在集合中的使用

    1.利用stream().forEach()循环处理List; List<String> list = Lists.newArrayList();//新建一个List 用的google提供 ...

  9. C++ Programming with TDD之二:CppUTest单元测试

    在之前一篇C++ Programming with TDD博客中,我带给大家gmock框架的简介(地址戳着里),今天我们继续本系列,带个大家C++中的单元测试框架CppUTest的介绍. CppUTe ...

  10. P2258 子矩阵 (搜索,动态规划)

    题目链接 Solution 搜索+DP. 刚好把搜索卡死的数据范围... 然后应该可以很容易想到枚举行的情况,然后分列去DP. 行的情况直接全排列即可,复杂度最高 \(O(C_{16}^{8})\). ...