PropertyGrid控件 分类(Category)及属性(Property)排序

最近在做表单设计器,设计器上的控件都是我们自己封装的,但每个属性类别里的属性是按照属性的拼音排序的,现在想按照PropertyIndex标识进行排序(PropertyIndex的后三位是用来标识编辑器的)。

具体实现如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.ComponentModel;
using HC.Test.ComponentModel;
using HC.Test.Common;
using System.Data;
using HC.Test.Common.ComponentModel;
using System.Xml.Serialization;
using System.Windows.Forms;
using HC.Test.Forms.ControlConfig;
using System.Collections;namespace HC.Test.Designer.UI
{public class ControlEditorTypeDescriptionProvider : TypeDescriptionProvider{protected TypeDescriptionProvider _baseProvider;private PropertyDescriptorCollection _propCache;protected Dictionary<Type, Type> dictEdtor;/// <summary>///  属性Editor字典///  Key:Attribute Value:Editor/// </summary>public Dictionary<Type, Type> EdtorDictionary{get{return dictEdtor;}}public ControlEditorTypeDescriptionProvider(): base(){dictEdtor = new Dictionary<Type, Type>();}/// <summary>/// /// </summary>/// <param name="t">要修改属性的基类</param>public ControlEditorTypeDescriptionProvider(Type t): this(){_baseProvider = TypeDescriptor.GetProvider(t);}public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance){PropertiesTypeDescriptor typeDes = new PropertiesTypeDescriptor(_baseProvider.GetTypeDescriptor(objectType, instance), this, objectType);return typeDes;}}/// <summary>/// 属性集合的描述/// </summary>public class PropertiesTypeDescriptor : CustomTypeDescriptor{private Type objType;private DataTable dtConfig = new DataTable();private ControlEditorTypeDescriptionProvider provider;public PropertiesTypeDescriptor(ICustomTypeDescriptor descriptor, ControlEditorTypeDescriptionProvider provider, Type objType): base(descriptor){if (provider == null){throw new ArgumentNullException("provider");}if (descriptor == null){throw new ArgumentNullException("descriptor");}if (objType == null){throw new ArgumentNullException("objectType");}this.objType = objType;this.provider = provider;}/// <summary>/// 获取属性列表/// </summary>/// <param name="attributes"></param>/// <returns></returns>public override PropertyDescriptorCollection GetProperties(Attribute[] attributes){try{string nowIndexCode = "";Type editor;Type editorControl;Attribute abEvent;EventPropertyDescriptor des;bool showPageSize = true;//从dll中读取配置Dictionary<string, ControlEditorType> dictConfig = PubFunc.GetPropertyEditor();ArrayList orderedProperties = new ArrayList();foreach (PropertyDescriptor prop in base.GetProperties(attributes)){                   #region  控件、表单部分属性屏蔽//屏蔽所有控件数据Category 数据 属性if (((System.ComponentModel.MemberDescriptor)(prop)).Category == "数据" || ((System.ComponentModel.MemberDescriptor)(prop)).Category == "Data"){continue;}//屏蔽所有控件数据Category 杂项 属性if (((System.ComponentModel.MemberDescriptor)(prop)).Category == "杂项" || ((System.ComponentModel.MemberDescriptor)(prop)).Category == "Misc"){continue;}#endregion#region 屏蔽不需要显示的属性switch (((System.ComponentModel.MemberDescriptor)(prop)).Name){case "DisplayStyleEnum":CommonHelpDisplayStyleEnum displayType = (CommonHelpDisplayStyleEnum)prop.GetValue(this);if (displayType == CommonHelpDisplayStyleEnum.TreeStyle){showPageSize = false;}break;case "PageSize":if (!showPageSize){continue;}break;}#endregionabEvent = prop.Attributes[typeof(PropertyIndexAttribute)];if (abEvent != null && abEvent is PropertyIndexAttribute){nowIndexCode = ((PropertyIndexAttribute)abEvent).IndexCode;#region 事件编辑器处理if (nowIndexCode.Length > 6){//最后三位000标识 不带编辑器if (nowIndexCode.Substring(6, 3) == "000"){orderedProperties.Add(new PropertyOrderPair(prop.DisplayName, int.Parse(nowIndexCode), prop));continue;}foreach (var cet in dictConfig){if (cet.Key == nowIndexCode.Substring(6, 3)){//根据配置文件的序列号,获取出全名HC.Test.Designer.UI.EventActionEditorControl,放入下面的函数中                          editorControl = ReflectionActivator.GetType("HC.Test.Designer.UI", cet.Value.EditorName);if (editorControl == null){orderedProperties.Add(new PropertyOrderPair(prop.DisplayName, int.Parse(nowIndexCode), prop));break;}if (cet.Value.EditorType == "CommonTypeDropDownEditor"){editor = ReflectionActivator.GetGenericType("HC.Test.Common.Design", "HC.Test.Common.Design.GenericDropDownControlEditor`1", new Type[] { editorControl });}else{editor = ReflectionActivator.GetGenericType("HC.Test.Common.Design", "HC.Test.Common.Design.ModalFormEditor`1", new Type[] { editorControl });}des = new EventPropertyDescriptor(prop, editor);orderedProperties.Add(new PropertyOrderPair(prop.DisplayName, int.Parse(nowIndexCode), des));break;}}}#endregionelse{orderedProperties.Add(new PropertyOrderPair(prop.DisplayName, 0, prop));continue;}}else{orderedProperties.Add(new PropertyOrderPair(prop.DisplayName, 0, prop));}}//属性集合按照PropertyIndexAttribute及DisplayName排序orderedProperties.Sort();PropertyDescriptorCollection propsTemp = new PropertyDescriptorCollection(null);foreach (PropertyOrderPair pop in orderedProperties){propsTemp.Add(pop.Property);}return propsTemp;//ArrayList propertyNames = new ArrayList();//foreach (PropertyOrderPair pop in orderedProperties)//{//    propertyNames.Add(pop.Name);//}//return pdc.Sort((string[])propertyNames.ToArray(typeof(string)));}catch{throw;}}}/// <summary>/// 属性 描述(属性的属性)/// </summary>public class EventPropertyDescriptor : PropertyDescriptor{Type editor = null;PropertyDescriptor prop;public EventPropertyDescriptor(PropertyDescriptor descr, Type editor): base(descr){this.prop = descr;this.editor = editor;          }/// <summary>/// 获取Editor;/// </summary>/// <param name="editorBaseType"></param>/// <returns></returns>public override object GetEditor(Type editorBaseType){object obj = base.GetEditor(editorBaseType);if (obj == null){obj = ReflectionActivator.CreateInstace(editor);}return obj;}public override bool CanResetValue(object component){return prop.CanResetValue(component);}public override Type ComponentType{get { return prop.ComponentType; }}public override object GetValue(object component){return prop.GetValue(component);}public override bool IsReadOnly{get { return prop.IsReadOnly; }}public override Type PropertyType{get { return prop.PropertyType; }}public override void ResetValue(object component){prop.ResetValue(component);}public override void SetValue(object component, object value){prop.SetValue(component, value);}public override bool ShouldSerializeValue(object component){return prop.ShouldSerializeValue(component);}}}
PropertyIndexAttribute类:

    /// <summary>/// 属性信息的顺序分类等信息/// 字段或者属性等 可序列化的信息上/// 现在是一共9位,最后3位用来标识编辑器 最后三位000 默认不会识别编辑器/// 中间三位用来属性排序/// </summary>[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]public class PropertyIndexAttribute : Attribute{private string indexCode;/// <summary>/// 标识/// </summary>public string IndexCode{get{return indexCode;}set{indexCode = value;}}/// <summary>/// /// </summary>/// <param name="indexCode"></param>public PropertyIndexAttribute(string indexCode){this.indexCode = indexCode;}}
排序部分:

  #region Helper Class - PropertyOrderPairpublic class PropertyOrderPair : IComparable{private int _order;private string _name;public string Name{get{return _name;}}private PropertyDescriptor _property;public PropertyDescriptor Property{get{return _property;}}public PropertyOrderPair(string name, int order, PropertyDescriptor property){_order = order;_name = name;_property = property;}public int CompareTo(object obj){//// Sort the pair objects by ordering by order value// Equal values get the same rank//int otherOrder = ((PropertyOrderPair)obj)._order;if (otherOrder == _order){//// If order not specified, sort by name//string otherName = ((PropertyOrderPair)obj)._name;return string.Compare(_name, otherName);}else if (otherOrder > _order){return -1;}return 1;}}#endregion#region Helper Class - PropertyOrderAttribute 未用//[AttributeUsage(AttributeTargets.Property)]//public class PropertyOrderAttribute : Attribute//{//    ////    // Simple attribute to allow the order of a property to be specified//    ////    private int _order;//    public PropertyOrderAttribute(int order)//    {//        _order = order;//    }//    public int Order//    {//        get//        {//            return _order;//        }//    }//}#endregion
设置PropertyGrid控件的属性:


用法:

为每个属性添加属性:[PropertyIndex("103001000")]

比如:

		[Category("掩码")][Browsable(true)][DisplayName("掩码类型")]//[Description("设置执行单击事件的快捷键")][PropertyIndex("103001000")]public DevExpress.XtraEditors.Mask.MaskType MaskType{get{return this.BaseTextEdit.Properties.Mask.MaskType;}set{this.BaseTextEdit.Properties.Mask.MaskType = value;}}[Category("掩码")][Browsable(true)][DisplayName("忽略空白")][Description("对于 Simple、Regular 和 RegEx 掩码类型,MaskProperties.IgnoreMaskBlank 属性是有效的。 如果此属性值设置为 true,那么空白编辑器会失去焦点。 如果编辑器的取值仅部分完成,那么焦点不能被移出此编辑器,直至最终用户输入了完整的取值或者通过清除编辑器框而清除了取值。 如果此属性值设置为 false,那么焦点不能移出此编辑器,直至完整输入取值。 ")][PropertyIndex("103006000")]public bool IgnoreMaskBlank{get{return this.BaseTextEdit.Properties.Mask.IgnoreMaskBlank;}set{this.BaseTextEdit.Properties.Mask.IgnoreMaskBlank = value;}}[Category("掩码")][Browsable(true)][DisplayName("格式占位符")][Description("对于 Simple、Regular 和 RegEx 掩码类型,使用由 MaskProperties.PlaceHolder 属性确定的特殊字符来呈现编辑框中的占位符。 可以使用该属性来改变默认的占位符 (“_”符)。 对于 RegEx 掩码类型,通过把 MaskProperties.ShowPlaceHolders 属性设置为 false,可以隐藏占位符。 ")][PropertyIndex("103007000")]public char PlaceHolder{get{return this.BaseTextEdit.Properties.Mask.PlaceHolder;}set{this.BaseTextEdit.Properties.Mask.PlaceHolder = value;}}[Category("掩码")][Browsable(true)][DisplayName("错误提示音")][Description("对于所有类型的掩码,Boolean 型的 MaskProperties.BeepOnError 属性都是可用的。 把此属性设置为 true,当最终用户试图键入一个无效字符串时允许响铃。 假定使用了 Numeric 类型的掩码。 在这种情况下,最终用户每次试图键入非数字字符时,编辑器都将发出一段提示声音。")][PropertyIndex("103005000")]public bool BeepOnError{get{return this.BaseTextEdit.Properties.Mask.BeepOnError;}set{this.BaseTextEdit.Properties.Mask.BeepOnError = value;}}[Category("掩码")][Browsable(true)][DisplayName("自动填充")][Description("对于 RegEx 掩码类型,可以启用自动完成功能。 在这种模式中,编辑器将尝试完成已经由最终用户部分输入的取值。")][PropertyIndex("103004000")]public DevExpress.XtraEditors.Mask.AutoCompleteType AutoComplete{get{return this.BaseTextEdit.Properties.Mask.AutoComplete;}set{this.BaseTextEdit.Properties.Mask.AutoComplete = value;}}[Category("掩码")][Browsable(true)][DisplayName("保存格式字符串")][Description("对于 Simple 和 Regular 掩码类型,可以指定是否总是把显示的掩码字符 (原义字符) 包括在编辑器的取值内。 换句话说,你可以控制那些字符是否出现在由 BaseEdit.EditValue 属性返回的取值中。 要使这些字符无法被访问,则必须把 MaskProperties.SaveLiteral 属性设置为 false。 在这种情况下,如果显示的取值是“(555)123-76-34”,那么由 BaseEdit.EditValue 属性返回的取值就是“5551237634”。 ")][PropertyIndex("103008000")]public bool SaveLiteral{get{return this.BaseTextEdit.Properties.Mask.SaveLiteral;}set{this.BaseTextEdit.Properties.Mask.SaveLiteral = value;}}[Category("掩码")][Browsable(true)][DisplayName("掩码字符串")][Description("掩码字符串标识了数据输入模板。 可以使用预定义的掩码字符串,或者构建自己的掩码表达式, 应该根据掩码类型来设置掩码字符串。")][PropertyIndex("103002000")]public string EditMask{get{return this.BaseTextEdit.Properties.Mask.EditMask;}set{this.BaseTextEdit.Properties.Mask.EditMask = value;}}[Category("掩码")][Browsable(true)][DisplayName("显示格式占位符")][Description("对于 Simple、Regular 和 RegEx 掩码类型,使用由 MaskProperties.PlaceHolder 属性确定的特殊字符来呈现编辑框中的占位符。 可以使用该属性来改变默认的占位符 (“_”符)。 对于 RegEx 掩码类型,通过把 MaskProperties.ShowPlaceHolders 属性设置为 false,可以隐藏占位符。 ")][PropertyIndex("103003000")]public bool ShowPlaceHolders{get{return this.BaseTextEdit.Properties.Mask.ShowPlaceHolders;}set{this.BaseTextEdit.Properties.Mask.ShowPlaceHolders = value;}}
效果:


如果使用网络上的sort排序代码(感觉不对,于是没有采用):

  //ArrayList propertyNames = new ArrayList();//foreach (PropertyOrderPair pop in orderedProperties)//{//    propertyNames.Add(pop.Name);//}//return pdc.Sort((string[])propertyNames.ToArray(typeof(string)));
效果如下:



本文参考:

PropertyGrid排序

Ordering Items in the Property Grid

PropertyGrid类别排序实现,可以参考:

点击打开链接 

具体实现如下:

属性控件PropertyGrid事件:

 #region  属性分组排序部分private void propertyGrid_SelectedObjectsChanged(object sender, EventArgs e){propertyGrid.Tag = propertyGrid.PropertySort;propertyGrid.PropertySort = PropertySort.CategorizedAlphabetical;propertyGrid.Paint += new PaintEventHandler(propertyGrid_Paint);    }private void propertyGrid_Paint(object sender, PaintEventArgs e){var categorysinfo = propertyGrid.SelectedObject.GetType().GetField("categorys", BindingFlags.NonPublic | BindingFlags.Instance);if (categorysinfo != null){var categorys = categorysinfo.GetValue(propertyGrid.SelectedObject) as List<String>;propertyGrid.CollapseAllGridItems();GridItemCollection currentPropEntries = typeof(PropertyGrid).GetField("currentPropEntries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(propertyGrid) as GridItemCollection;var newarray = currentPropEntries.Cast<GridItem>().OrderBy((t) => categorys.IndexOf(t.Label)).ToArray();currentPropEntries.GetType().GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(currentPropEntries, newarray);propertyGrid.ExpandAllGridItems();propertyGrid.PropertySort = (PropertySort)propertyGrid.Tag;}propertyGrid.Paint -= new PaintEventHandler(propertyGrid_Paint);}
由于我用的是:


所以在反射的时候,用的是:

GridItemCollection currentPropEntries = typeof(PropertyGrid).GetField("currentPropEntries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(propertyGrid) as GridItemCollection;
而非参考文章中的:

GridItemCollection currentPropEntries = propertyGrid1.GetType().GetField("currentPropEntries", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(propertyGrid1) as GridItemCollection;


控件中的使用:



效果:


完成!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/459566.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css3标签

-moz代表firefox浏览器私有属性 -ms代表ie浏览器私有属性 -webkit代表chrome、safari私有属性 -o代表opera私有属性 border-radius:2em; 向div元素添加圆角边框&#xff0c;这是一种缩小写法&#xff0c;等价于: border-top-left-radius:2em; border-top-right-radius:2em; bor…

用计算机计算出密码,自带计算器的密码

手机、电脑都会有自带的计算器&#xff0c;用惯了简易的计算器功能&#xff0c;不知道有没有感觉 iPhone 自带的计算器难用&#xff1f;后来才发现原来它还可以使用科学计算器进行指数函数、对数函数和三角函数的计算。只需要将 iPhone 转到横排模式就可以&#xff1a;这算不算…

PHP内核探索之变量(6)- 后续内核探索系列大纲备忘

年前因为工作比较饱和&#xff0c;现在又忙着换工作的事情&#xff0c;基本停止了对博文的更新。后续的博文&#xff0c;还是慢慢补上吧。 为了不至于过于发散&#xff0c;先搞个未成形的大纲&#xff0c;如下&#xff1a; PHP内核探索之变量 不平凡的字符串  PHP内核探索之…

ios 开发日记 21 -自动处理键盘事件的第三方库:IQKeyboardManager

我们写界面要考虑很多用户体验问题&#xff0c;键盘事件的响应就是比较麻烦的一种。我们需要监听键盘事件&#xff0c;考虑点击背景收起键盘、考虑键盘遮挡输入框问题等等&#xff0c;而且每个界面都要做这么一套。这个库帮我们解决了这个事情。 这个库的下载地址&#xff1a;h…

shopify在哪里填写html,[Shopify开店教程]添加嵌入代码

添加嵌入代码在Shopify管理员中创建购买按钮后&#xff0c;您就可以将其添加到您自己的网站或博客中。将嵌入代码添加到您网站的源HTML的过程有所不同&#xff0c;具体取决于您希望购买按钮和购物车在您的发布平台上显示的方式和位置&#xff0c;以及有时您在该平台上使用的主题…

activity生命周期图

转载于:https://www.cnblogs.com/aqianglala/p/4344431.html

华硕台式计算机光盘怎么启动不了,华硕笔记本怎么用光盘重装系统 笔记本重装系统失败怎么办...

华硕笔记本是现在非常热门的笔记本品牌&#xff0c;很多的华硕笔记本用户在重装系统的时候&#xff0c;大多数会用上光盘&#xff0c;这种重装方式较为简单&#xff0c;所以备受青眯&#xff0c;不过呢还是有很多电脑用户不知道怎么用光盘重装系统&#xff0c;没关系&#xff0…

怎么安装Win10,硬盘安装Win10系统图文教程

2019独角兽企业重金招聘Python工程师标准>>> http://jingyan.baidu.com/article/f25ef254613ffd482c1b8236.html 分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友…

iOS高级必备

1.你使用过Objective-C的运行时编程&#xff08;Runtime Programming&#xff09;么&#xff1f;如果使用过&#xff0c;你用它做了什么&#xff1f;你还能记得你所使用的相关的头文件或者某些方法的名称吗&#xff1f; Objecitve-C的重要特性是Runtime&#xff08;运行时&…

游戏计算机重要参数,这真的很重要吗 游戏鼠标三大参数之谜

1游戏鼠标三大参数&#xff1a;采样率[中关村在线键鼠频道原创]游戏鼠标作为目前最受消费者关注的外设产品&#xff0c;其销量以及利润在市场上也是表现最为出色的&#xff0c;众多游戏外设厂商也推出各种各样的游戏鼠标&#xff0c;各种霸气的名字更是让我们看的眼花缭乱&…

[Android]Activity启动过程

Android系统启动加载流程&#xff1a; 参考图 Linux内核加载完毕启动init进程init进程fork出zygote进程zygote进程在ZygoteInit.main()中进行初始化的时候fork出SystemServer进程SystemServer进程开启的时候初始化ActivityThread和ActivityManagerService&#xff08;其它还有P…

CentOS 7 中firewall-cmd命令

在 CentOS 7 暂时开放 ftp 服务# firewall-cmd --add-serviceftp永久开放 ftp 服务# firewall-cmd --add-serviceftp --permanent永久关闭# firewall-cmd --remove-serviceftp --permanentsuccess让设定生效# systemctl restart firewalld检查设定是否生效# iptables -L -n | g…

计算机网络又称国际互联网,Internet属于( )。 A.国际互联网B.内部网C.局域网D.电话网 - 作业在线问答...

相关题目与解析Internet属于()。A.内部网B.局域网C.公用电话网D.国际互联网Internet称为()。A&#xff0e;国际互联网B&#xff0e;广域网C&#xff0e;局域网D&#xff0e;世界信息网INTERNET也称为()。A.局域网B.对等网C.国际互联网D.以太网因特网(Internet)又称A、局域网B、…

substring 在C#,Javascript,SQL 中index开始值

substring函数index参数在三个平台的开始值: 平台index参数开始值C#0Javascript0SQL1转载于:https://www.cnblogs.com/jimcsharp/p/4354192.html

Android的十六进制颜色值

颜色和不透明度 (alpha) 值以十六进制表示法表示。任何一种颜色的值范围都是 0 到 255&#xff08;00 到 ff&#xff09;。对于 alpha&#xff0c;00 表示完全透明&#xff0c;ff 表示完全不透明。表达式顺序是“aabbggrr”&#xff0c;其中“aaalpha”&#xff08;00 到 ff&am…

在线mod计算机,MOD大师教程 手把手教你改造电脑机箱

MOD将代替DIY风靡中国中国的DIY已经从P2时代极少数的用户发展到现在让品牌机头疼不已的庞大用户群体&#xff0c;电脑的DIY已经不能再被说成是一个技术了。那么追求个性的玩家们只能坐以待毙吗&#xff1f;当然不是了&#xff0c;于是MOD在国内也慢慢地兴盛起来。漂亮的机箱主题…

signals系列之一——基本用法

摘自&#xff1a;http://zengrong.net/post/1504.htm转载于:https://www.cnblogs.com/man-li/p/4354201.html

桌面上的文件使计算机变慢吗,电脑用久了会变卡怎么办?让电脑变得流畅方法图解...

工作生活中我们的电脑时间用久了&#xff0c;就会变得很卡&#xff0c;那么如何做会让电脑变得流畅一点呢&#xff0c;小编教大家几招。步骤首先要保持windows桌面整洁&#xff0c;尽量少放一些文件&#xff0c;因为桌面上的文件都是放在C盘&#xff0c;电脑系统一般也是装在C盘…

FetchType与FetchMode的区别

使用例&#xff1a; OneToMany(mappedBy"item",cascadeCascadeType.ALL,fetchFetchType.EAGER) Fetch(valueFetchMode.SUBSELECT) 两者比较&#xff1a; 两者都是设定关联对象的加载策略。前者是JPA标准的通用加载策略注解属性&#xff0c; 后者是Hibernate自有加载…

计算机无线局域网毕业论文,谈教学设计《计算机网络》网络课程“无线局域网”单元的设计与开发大专毕业论文范文...

中文摘要4-5ABSTRACT5-91 引论9-221.1 不足的提出9-101.2 国内外探讨近况10-131.2.1 文献综述10-121.2.2 网络课程建设近况12-131.3 探讨目标以及作用131.3.1 探讨目标131.3.2 探讨作用131.4 探讨的策略13-141.5 探讨的思路14-221.5.1 任务驱动教学法15-181.5.2 MOODLE 平台介绍…