关闭

两点C#的propertyGrid的使用心得

标签: propertyGrid只读可见性
217人阅读 评论(0) 收藏 举报

第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; }
        }
复制代码
1
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

C#自定义PropertyGrid属性

最近用到了PropertyGrid,原来从来没用到过,拿在手里,一头雾水,经过一段时间研究后,大概理解了Property的使用方法,下面仔细剖析一下。 PropertyGrid控件就是Visual ...
  • jjhua
  • jjhua
  • 2014-04-07 13:40
  • 15919

C# 设计时动态改变实体在PropertyGrid中显示出来的属性

方法一: /// /// 实体属性处理 /// public class PropertyHandle { #region 反射控制只读、可见...
  • xunzaosiyecao
  • xunzaosiyecao
  • 2015-11-21 12:45
  • 2840

自定义propertygrid弹出属性编辑框

看别人写的不详尽,再次总结自己摸索出来的东西: 首先建立一个窗体,该窗体包含你要重新编辑的属性值等内容,下图是我的界面,其中只包含一个richtextbox。 在该窗体后台写代码如下(这两段代码足够...
  • u014722754
  • u014722754
  • 2015-07-28 18:21
  • 1784

C# PropertyGrid控件应用心得

  • 2016-09-23 09:19
  • 399KB
  • 下载

C# PropertyGrid控件应用心得

最近 最近项目中做一模块时偶发奇想,希望使用propertygrid的控件实现类似visual studio的属性样式,于是拿来一用,发现还真不是自己想象的那么简单,如果要实现一个比较好的展示,还真...
  • libingxin
  • libingxin
  • 2012-08-08 18:29
  • 1052

C# PropertyGrid控件应用心得

原文:http://blog.csdn.net/zzh87615/article/details/6027552 目录 PropertyGrid 控件简介  创建 PropertyGrid ...
  • jjiss318
  • jjiss318
  • 2012-04-24 00:00
  • 2767

C# PropertyGrid控件应用心得

地址:http://blog.csdn.net/luyifeiniu/article/details/5426960#自定义 PropertyGrid 控件 最近项目中做一模块时偶发奇想,希望使...
  • anlidengshiwei
  • anlidengshiwei
  • 2015-01-14 15:25
  • 553

c#——Winform PropertyGrid使用

最近被迫调到某部,协助一个配置工具的开发。 做winform的开发,这些控件yiji相关的知识还是在学校上课的时候学到的。工作之后,没有接触相关的开发。 使用的是SCSF框架,控件使用winform自...
  • Shiyaru1314
  • Shiyaru1314
  • 2016-07-15 19:26
  • 2420

C#在Winform中使用GMap.Net地图开发控件在离线模式下绘制两点路线

1.下载基于GMap.NET控件的WindowsForms程序的实例,可以直接引用这些dll文件编写地图应用软件。     我们所要用到其中的三个文件:          GMap.Net.Core....
  • lyss918
  • lyss918
  • 2016-03-19 14:07
  • 6733

c#中PropertyGrid 控件简介

PropertyGrid 控件简介 如果您使用过 Microsoft® Visual Basic® 或 Microsoft Visual Studio .NET,那么您一定使用过属性浏览器来浏览、查...
  • fyzs19891124
  • fyzs19891124
  • 2017-11-30 09:59
  • 41
    个人资料
    • 访问:767次
    • 积分:14
    • 等级:
    • 排名:千里之外
    • 原创:0篇
    • 转载:2篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档