两点C#的propertyGrid的使用心得
最近接触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。
private void button1_Click(object sender, EventArgs e)
{
Type readonlyType = typeof(System.ComponentModel.ReadOnlyAttribute);
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(propertyGrid1.SelectedObject);
FieldInfo fld = readonlyType.GetField("isReadOnly", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.CreateInstance);
AttributeCollection attrs = TypeDescriptor.GetAttributes(propertyGrid1.SelectedObject);
fld.SetValue(attrs[typeof(ReadOnlyAttribute)], gridReadOnly);
gridReadOnly = !gridReadOnly;
}
这里説一下,在找解决办法的时候,还去顺便了解了一下c#在运行时,动态添加Attribute的内容,这个内容留下次再记录好了。
还找到一篇讲反射可以通过FieldInfo.SetValue设置任何字段的值的文章:http://www.cnblogs.com/Laser_Lu/archive/2004/08/01/29171.html
第2点是PropertyGrid中使用TypeConverter
PropertyGrid中对于自定义的类型显示支持有限,最好是自己去实现自己的TypeConverter,把类型转换来进行显示。我写了一个简单的例子,把List类型转换成string。
public class MyColorConverter : TypeConverter
{
public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value == null)
{
return new List<int>();
}
string stringValue = value as string;
if (stringValue != null)
{
List<int> result = new List<int>();
string[] vs = stringValue.Split(new char[] { ',' });
foreach (string eachString in vs)
{
result.Add(int.Parse(eachString));
}
return result;
}
else
{
return base.ConvertFrom(context, culture, value);
}
} public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
} public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributes)
{
throw new Exception("The method or operation is not implemented.");
} public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
List<int> list = value as List<int>;
if (list != null && list.Count > )
{
StringBuilder sb = new StringBuilder();
foreach (int v in list)
{
sb.AppendFormat("{0},", v);
}
sb.Remove(sb.Length - , );
return sb.ToString();
}
return "";
}
else
{
return base.ConvertTo(context, culture, value, destinationType);
}
} public override bool CanConvertFrom(System.ComponentModel.ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
}
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的使用心得的更多相关文章
- 两点C#的propertyGrid的使用心得【转】
源文:http://www.cnblogs.com/bicker/p/3318934.html 最近接触C#的PropertyGrid比较多,得到了两个小心得记录一下. 第1点是关于控制Propert ...
- C# PropertyGrid控件应用心得
何处使用 PropertyGrid 控件 在应用程序中的很多地方,您都可以使用户与 PropertyGrid 进行交互,从而获得更丰富的编辑体验.例如,某个应用程序包含多个用户可以设置的“设置”或选项 ...
- C# PropertyGrid控件应用心得 【转】
源文 : http://blog.csdn.net/luyifeiniu/article/details/5426960 c#stringattributesobjectmicrosoftclass ...
- 关于CSS中float的两点心得以及清除浮动的总结
对一个元素运用float后,该元素将脱离正常文档流,这意味着: 1. 运用float后,该元素不再影响父元素的高度,如果一个元素的所有子元素都是float的话,那么该元素的高度是0,这样后面元素渲染的 ...
- PropertyGrid控件由浅入深(二):基础用法
目录 PropertyGrid控件由浅入深(一):文章大纲 PropertyGrid控件由浅入深(二):基础用法 控件的外观构成 控件的外观构成如下图所示: PropertyGrid控件包含以下几个要 ...
- C# 如何定义让PropertyGrid控件显示[...]按钮,并且点击后以下拉框形式显示自定义控件编辑属性值
关于PropertyGrid控件的详细用法请参考文献: 1.C# PropertyGrid控件应用心得 2.C#自定义PropertyGrid属性 首先定义一个要在下拉框显示的控件: using Sy ...
- windows类书的学习心得(转载)
原文网址:http://www.blogjava.net/sound/archive/2008/08/21/40499.html 现在的计算机图书发展的可真快,很久没去书店,昨日去了一下,真是感叹万千 ...
- 百度api使用心得体会
最近项目中在使用百度地图api,对于其中的一些有用的点做一些归纳整理,如有不对的地方,欢迎各位大神纠正指出. 一定要学会查找百度地图api提供的类参考网站:http://lbsyun.baidu.co ...
- System.Windows.Forms.PropertyGrid的使用
PropertyGrid 控件简介 .NET 框架 PropertyGrid 控件是 Visual Studio .NET 属性浏览器的核心.PropertyGrid 控件显示对象或类型的属性,并主要 ...
随机推荐
- 从今天开始写博客、托管代码到 Github
最近看了一篇文章,译名<简历危险>,原名<Resumes are dangerous>. 作者为Alex Maccaw,他有一篇文章曾经在网上流传甚广——<Traveli ...
- 小数点输出精度控制问题 .xml
pre{ line-height:1; color:#9f1d66; background-color:#d2d2d2; font-size:16px;}.sysFunc{color:#5d57ff; ...
- 句柄(handle)
< Back 句柄,在windows编程中用来标识: *.模块(module) *.任务(task) *.实例(instance) *.文件(file) *.内存块(block of memor ...
- 解决android.os.NetworkOnMainThreadException
好久不写Android代码手都生了,找出自己之前写的程序发现跑不了了,也没啥特别的错误提示,就看到一句有用的错误Caused by: android.os.NetworkOnMainThreadExc ...
- c语言的几个重要知识点
内存结构 这是核心中的核心,请仔细看完,充分理解,否则请不要看下一节内容. 每个程序一启动都有一个大小为4GB的内存,这个内存叫虚拟内存,是概念上的,真正能用到的,只是很小一部分,一般也就是在几百 ...
- yum 安装 php5.6 和 mysql5.6
安装 PHP rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm; rpm - ...
- JavaScript面向对象(01)--函数
在JavaScript中,函数和对象有区别,也有联系, 首先函数是一个对象,但是和对象存在一些区别如下: 1,不论在java还是js中,如果把一个对象赋值给另一个变量,那么,后者会指向前者对象所在的内 ...
- 查看MySql中每个IP的连接数
要统计数据库的连接数,我们通常情况下是统计总数,没有细分到每个IP上.现在要监控每个IP的连接数,实现方式如下: ) as ip , count(*) from information_schema. ...
- 2.VS2010C++各种后缀说明
相关资料:"http://blog.csdn.net/kibaamor/article/details/18700607""http://blog.chinaunix.n ...
- RS-232-C串口通讯协议解析(硬件接口协议)
http://www.dz3w.com/info/interface/0075524.html http://wenku.baidu.com/view/02cc247c27284b73f24250e3 ...