解决方案

C# PropertyGrid 简单使用

seo靠我 2023-09-25 08:48:03

目录

一、 导入数据

二、 PropertyGrid 的简单属性配置

三、 设置字段属性

四、 字段的下拉框

五、 多级展开

六、 显示内容的排序

6.1 属性排序

6.1.1 自定义排序

6.1.2 根据字段封装顺序SEO靠我

6.2 类别排序 

七、 闪屏问题

八、 主要参考

一、 导入数据

propertyGrid1.SelectedObject = new Level1(); 

显示Level1类中所有 public 属性 Get SEO靠我Set 封装的字段。 propertyGrid1.SelectedObject = new Level1();public class Level1 {privateSEO靠我 int nVal1;private int nVal2;private int nVal3;public int NVal1 { get => nVal1; set => nVal1 = valueSEO靠我; }public int NVal2 { get => nVal2; set => nVal2 = value; }public int NVal3 { get => nVal3; set => nSEO靠我Val3 = value; } }

propertyGrid1.SelectedObjects = new object[] { new Level1(), new Level2() }SEO靠我;

显示Level2 和 Level2 中所有公共属性  propertyGrid1.SelectedObjects = new object[] { new Level1(), nSEO靠我ew Level2() };public class Level1 {private int nVal1;private int nVal2;private int nVal3;pubSEO靠我lic int NVal1 { get => nVal1; set => nVal1 = value; }public int NVal2 { get => nVal2; set => nVal2 =SEO靠我 value; }public int NVal3 { get => nVal3; set => nVal3 = value; } } public class LevSEO靠我el2 {private int nVal3;private int nVal4;private int nVal5;public int NVal3 { get => nVal3; SEO靠我set => nVal3 = value; }public int NVal4 { get => nVal4; set => nVal4 = value; }public int NVal5 { geSEO靠我t => nVal5; set => nVal5 = value; } }

二、 PropertyGrid 的简单属性配置

BackColor 更改其背景色。HelpBackColor 更SEO靠我改助窗口背景色。HelpForeColor 更改助窗口字体颜色。HelpVisible 显示隐藏帮助窗口。ToolbarVisible 显示隐藏工具栏。LargeButtons 显示大型工具栏按钮。PSEO靠我ropertySort 按字母顺序对属性进行排序。BackColor 更改拆分器颜色。LineColor 更改网格线和边框。

三、 设置字段属性

DescriptionAttribute - 设置属性在属SEO靠我性下方的说明帮助窗格中显示的属性的文本。 这是为具有焦点的活动属性提供帮助文本的有用方法。 将此属性应用于 MaxRepeatRate 该属性。CategoryAttribute 设置属性在网格中所属SEO靠我的类别。 当需要按类别名称分组的属性时,这非常有用。 如果属性未指定类别,则会将其分配给 Misc 类别。 将此属性应用于所有属性。BrowsableAttribute – 指示属性是否显示在网格中。SEO靠我 如果要从网格中隐藏属性,这非常有用。 默认情况下,公共属性始终显示在网格中。 将此属性应用于 SettingsChanged 该属性。ReadOnlyAttribute – 指示属性是否为只读。 如SEO靠我果要使属性在网格中不可编辑,这非常有用。 默认情况下,具有 get 和 set 访问器函数的公共属性在网格中可编辑。 将此属性应用于 AppVersion 该属性。DefaultValueAttribSEO靠我ute – 标识属性的默认值。 如果想要为属性提供默认值,然后确定该属性的值是否不同于默认值,则这非常有用。 将此属性应用于所有属性。DefaultPropertyAttribute – 标识类的默认SEO靠我属性。 类的默认属性在网格中选择类时首先获取焦点。 将此属性应用于 AppSettings 类。DisplayNameAttribute - 实际显示的名称 [DefaultPropSEO靠我erty("NVal1")] public class Level1 {private int nVal1;private int nVal2;private int SEO靠我nVal3;[Category("Level"), DefaultValue("123"), ReadOnly(false), Browsable(true), Description("This ISEO靠我s Description")]public int NVal1 { get => nVal1; set => nVal1 = value; }[Category("Level"),BrowsableSEO靠我(false)]public int NVal2 { get => nVal2; set => nVal2 = value; }[Category("Level"), DefaultValue("45SEO靠我6"), ReadOnly(true)]public int NVal3 { get => nVal3; set => nVal3 = value; } }

四、 字段的下拉框

常用属性 SEO靠我PropertyGrid 中已经封装了下拉框属性

字符串:

1. 通过继承重写 StringConverter 函数

/* 创建从类型转换器类继承的类。 * 由于属性 DefaultFileName 属于 SEO靠我String 类型* 因此可以从 StringConverter 继承。 * 如果属性类型的类型转换器不存在,则可以从 * TypeConverter 继承;在这种情况下,不需要这样做。*/ SEO靠我 public class MyStringConverter : StringConverter { //重写 GetStandardValuesSupportSEO靠我ed 方法并返回 true 以指示此对象支持可从列表中选择的标准值集。 public override bool GetStandardValuesSupported( ITypeDeSEO靠我scriptorContext context) {return true; }/* 重写 GetStandardValues 方法,并返回用标准值填充的 StandaSEO靠我rdValuesCollection 。 * 创建 StandardValuesCollection 的一种方法是在构造函数中提供值数组。 * 对于选项窗口应用程序,可以使用填充有建议的默认文件名的 SEO靠我字符串 数组。*/ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext SEO靠我context) {return new StandardValuesCollection(new string[]{"Str2", "Str3", "Str4"}); SEO靠我 }/* (可选) 如果希望用户能够键入不在下拉列表中的值,* 请重写 GetStandardValuesExclusive 方法并返回 false。 * 这基本上将下拉列表样式更改为组合框样式。*/SEO靠我 public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {reSEO靠我turn false; }

2. 通过Enum.ToString()实现,将String[] 变为 Enum,通过 Enum 实现下拉框

public class Level1 SEO靠我 {private bool bVal = true;private Size sizeVal = new Size(100,200);private Font fontVal= new FontSEO靠我("宋体", 9, FontStyle.Regular);private Color colVal = Color.Red;private EnumVal eVal = EnumVal.E02;priSEO靠我vate String sVal = "Str1";[CategoryAttribute("下拉框")]public bool BVal { get => bVal; set => bVal = vaSEO靠我lue; }[CategoryAttribute("下拉框")]public Size SizeVal { get => sizeVal; set => sizeVal = value; }[CateSEO靠我goryAttribute("下拉框")]public Font FontVal { get => fontVal; set => fontVal = value; }[CategoryAttribuSEO靠我te("下拉框")]public Color ColVal { get => colVal; set => colVal = value; }[CategoryAttribute("下拉框")]pubSEO靠我lic EnumVal EVal { get => eVal; set => eVal = value; }[CategoryAttribute("下拉框"), TypeConverter(typeoSEO靠我f(MyStringConverter))]public string SVal { get => sVal; set => sVal = value; } }

五、 多级展开

publiSEO靠我c class Level1 {private SpellingOptions spell = new SpellingOptions();/* 6. 将 TypeConverterASEO靠我ttribute 应用于示例中的类 SpellingOptions 目标类。*/[TypeConverterAttribute(typeof(SpellingOptionsConverter))]puSEO靠我blic SpellingOptions Spell { get => spell; set => spell = value; } }public class SpellingOptSEO靠我ions {private bool spellCheckWhileTyping = true;private bool spellCheckCAPS = false;private SEO靠我bool suggestCorrections = true;[DefaultValueAttribute(true)]public bool SpellCheckWhileTyping{get { SEO靠我return spellCheckWhileTyping; }set { spellCheckWhileTyping = value; }}[DefaultValueAttribute(false)]SEO靠我public bool SpellCheckCAPS{get { return spellCheckCAPS; }set { spellCheckCAPS = value; }}[DefaultValSEO靠我ueAttribute(true)]public bool SuggestCorrections{get { return suggestCorrections; }set { suggestCorrSEO靠我ections = value; }} }/* 1. 创建继承自 ExpandableObjectConverter 的类。* 若要获取 PropertyGrid 以展开 SpelliSEO靠我ngOptions 该属性,需要创建 TypeConverter。 * TypeConverter 提供了一种从一种类型转换为另一种类型的方法。 * PropertyGrid 使用 TypeConveSEO靠我rter 将对象类型转换为字符串,该字符串用于在网格中显示对象值。 * 在编辑期间, TypeConverter 将从 String 转换回对象类型。 * .NET Framework提供了 ExpaSEO靠我ndableObjectConverter 类,以便更轻松地执行此操作。*/ public class SpellingOptionsConverter : ExpandableObjSEO靠我ectConverter {/* 2. 如果参数与使用此类型的SpellingOptions转换器的类相同,* 则重写 CanConvertTo 方法并返回 truedestinatiSEO靠我onType;* 否则,返回基类 CanConvertTo 方法的值。*/ public override bool CanConvertTo(ITypeDescriptorContext conteSEO靠我xt, System.Type destinationType){if (destinationType == typeof(SpellingOptions))return true;return bSEO靠我ase.CanConvertTo(context, destinationType);}/* 3. 重写 ConvertTo 方法,并确保 destinationType 参数是 字符串 ,* 并且该SEO靠我值与使用此类型转换器 SpellingOptions 的类(示例中的类) 的类型相同。 * 如果任一情况为 false,则返回基类 ConvertTo 方法的值;* 否则返回值对象的字符串表示形式。 SEO靠我字符串表示形式需要用唯一分隔符分隔类的每个属性。 * 由于整个字符串将显示在 PropertyGrid 中,* 因此你需要选择一个不减去可读性的分隔符;逗号通常效果良好。*/ public overrSEO靠我ide object ConvertTo(ITypeDescriptorContext context,CultureInfo culture,object value,System.Type desSEO靠我tinationType){if (destinationType == typeof(System.String) &&value is SpellingOptions){SpellingOptioSEO靠我ns so = (SpellingOptions)value;return "Typing:" + so.SpellCheckWhileTyping +", CAPS: " + so.SpellCheSEO靠我ckCAPS +", Suggest: " + so.SuggestCorrections;}return base.ConvertTo(context, culture, value, destinSEO靠我ationType);}/* 4. (可选) 可以通过指定类型转换器可以从字符串转换来启用对网格中* 对象的字符串表示形式的编辑。 为此,请先重写 CanConvertFrom 方法,* 如果源 TySEO靠我pe 参数的类型为 String,则返回 true;否则,* 返回基类 CanConvertFrom 方法的值。*/ public override bool CanConvertFrom(ITypeSEO靠我DescriptorContext context,System.Type sourceType){if (sourceType == typeof(string))return true;returSEO靠我n base.CanConvertFrom(context, sourceType);}/* 5. 若要启用对对象的基类的编辑,* 还需要重写 ConvertFrom 方法,并确保值参数为 StrinSEO靠我g。 * 如果不是 String,则返回基类 ConvertFrom 方法的值;* 否则,请根据值参数返回类的新实例, (SpellingOptions 示例中的类) 。 * 需要从值参数分析类的每个SEO靠我属性的值。 * 了解在 ConvertTo 方法中创建的带分隔符的字符串的格式将有助于执行分析。*/public override object ConvertFrom(ITypeDescriptorSEO靠我Context context, CultureInfo culture, object value){if (value is string){try{string s = (string)valuSEO靠我e;int colon = s.IndexOf(:);int comma = s.IndexOf(,);if (colon != -1 && comma != -1){string checkWhilSEO靠我eTyping = s.Substring(colon + 1,(comma - colon - 1));colon = s.IndexOf(:, comma + 1);comma = s.IndexSEO靠我Of(,, comma + 1);string checkCaps = s.Substring(colon + 1,(comma - colon - 1));colon = s.IndexOf(:, SEO靠我comma + 1);string suggCorr = s.Substring(colon + 1);SpellingOptions so = new SpellingOptions();so.SpSEO靠我ellCheckWhileTyping = Boolean.Parse(checkWhileTyping);so.SpellCheckCAPS = Boolean.Parse(checkCaps);sSEO靠我o.SuggestCorrections = Boolean.Parse(suggCorr);return so;}}catch{throw new ArgumentException( "Can nSEO靠我ot convert " + (string)value + " to type SpellingOptions");}}return base.ConvertFrom(context, culturSEO靠我e, value);} }

六、 显示内容的排序

6.1 属性排序

PropertyGrid 默认支持的排序方式自定义顺序的排序方式根据字段封装顺序的排序方式

6.1.1 自定义排序

[TypeSEO靠我Converter(typeof(PropertySorter))] public class Level1 {int n01 = 1;int n02 = 2;int SEO靠我n03 = 3;int n04 = 4;int n05 = 5;int n06 = 6;[PropertyOrder(1)]public int N01 { get => n01; set => n0SEO靠我1 = value; }[PropertyOrder(2)]public int N04 { get => n04; set => n04 = value; }[PropertyOrder(3)]puSEO靠我blic int N02 { get => n02; set => n02 = value; }[PropertyOrder(4)]public int N05 { get => n05; set =SEO靠我> n05 = value; }[PropertyOrder(5)]public int N03 { get => n03; set => n03 = value; }[PropertyOrder(6SEO靠我)]public int N06 { get => n06; set => n06 = value; } }public class PropertySorter : ExpandabSEO靠我leObjectConverter {public override bool GetPropertiesSupported(ITypeDescriptorContext contexSEO靠我t){return true;}public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext coSEO靠我ntext, object value, Attribute[] attributes){//// This override returns a list of properties in ordeSEO靠我r//PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributes);ArrayList ordeSEO靠我redProperties = new ArrayList();foreach (PropertyDescriptor pd in pdc){Attribute attribute = pd.AttrSEO靠我ibutes[typeof(PropertyOrderAttribute)];if (attribute != null){//// If the attribute is found, then cSEO靠我reate an pair object to hold it//PropertyOrderAttribute poa = (PropertyOrderAttribute)attribute;ordeSEO靠我redProperties.Add(new PropertyOrderPair(pd.Name, poa.Order));}else{//// If no order attribute is speSEO靠我cifed then given it an order of 0//orderedProperties.Add(new PropertyOrderPair(pd.Name, 0));}}//// PSEO靠我erform the actual order using the value PropertyOrderPair classes// implementation of IComparable toSEO靠我 sort//orderedProperties.Sort();//// Build a string list of the ordered names//ArrayList propertyNamSEO靠我es = new ArrayList();foreach (PropertyOrderPair pop in orderedProperties){propertyNames.Add(pop.NameSEO靠我);}//// Pass in the ordered list for the PropertyDescriptorCollection to sort by//return pdc.Sort((sSEO靠我tring[])propertyNames.ToArray(typeof(string)));} }[AttributeUsage(AttributeTargets.Property)SEO靠我] public class PropertyOrderAttribute : Attribute {//// Simple attribute to allow thSEO靠我e order of a property to be specified//private int _order;public PropertyOrderAttribute(int order){_SEO靠我order = order;}public int Order{get{return _order;}} }public class PropertyOrderPair : ICompSEO靠我arable {private int _order;private string _name;public string Name{get{return _name;}}publicSEO靠我 PropertyOrderPair(string name, int order){_order = order;_name = name;}public int CompareTo(object SEO靠我obj){//// Sort the pair objects by ordering by order value// Equal values get the same rank//int othSEO靠我erOrder = ((PropertyOrderPair)obj)._order;if (otherOrder == _order){//// If order not specified, sorSEO靠我t by name//string otherName = ((PropertyOrderPair)obj)._name;return string.Compare(_name, otherName)SEO靠我;}else if (otherOrder > _order){return -1;}return 1;} }

6.1.2 根据字段封装顺序

[TypeConverter(typeof(PSEO靠我ropertySorter))] public class Level1 {int n01 = 1;int n02 = 2;int n03 = 3;int n04 = SEO靠我4;int n05 = 5;int n06 = 6;public int N01 { get => n01; set => n01 = value; }public int N04 { get => SEO靠我n04; set => n04 = value; }public int N02 { get => n02; set => n02 = value; }public int N05 { get => SEO靠我n05; set => n05 = value; }public int N03 { get => n03; set => n03 = value; }public int N06 { get => SEO靠我n06; set => n06 = value; } }public class PropertySorter : ExpandableObjectConverter SEO靠我{public override bool GetPropertiesSupported(ITypeDescriptorContext context){return true;}public oveSEO靠我rride PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, AttriSEO靠我bute[] attributes){PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(value, attributesSEO靠我);ArrayList propertyNames = new ArrayList();foreach (PropertyDescriptor pd in pdc)propertyNames.Add(SEO靠我pd.Name);return pdc.Sort((string[])propertyNames.ToArray(typeof(string)));} }

6.2 类别排序 

1. PropSEO靠我ertyGrid.PropertySort = CategorizedAlphabetical

2. 数据类中添加类别排序List

private List<String> categorys = newSEO靠我 List<string>() { ... };

 3. 添加 PropertyGrid 的 Paint 事件

private void propertyGrid1_Paint(object sender,SEO靠我 PaintEventArgs e) {var categorysinfo = propertyGrid1.SelectedObject.GetType().GetField("catSEO靠我egorys", BindingFlags.NonPublic | BindingFlags.Instance);if (categorysinfo != null){var categorys = SEO靠我categorysinfo.GetValue(propertyGrid1.SelectedObject) as List<String>;propertyGrid1.CollapseAllGridItSEO靠我ems();GridItemCollection currentPropEntries = typeof(PropertyGrid).GetField("currentPropEntries", BiSEO靠我ndingFlags.NonPublic | BindingFlags.Instance).GetValue(propertyGrid1) as GridItemCollection;var newaSEO靠我rray = currentPropEntries.Cast<GridItem>().OrderBy((t) => categorys.IndexOf(t.Label)).ToArray();currSEO靠我entPropEntries.GetType().GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance).SetValuSEO靠我e(currentPropEntries, newarray);propertyGrid1.ExpandAllGridItems();object obj = propertyGrid1.Tag;ifSEO靠我 (obj != null)propertyGrid1.PropertySort = (PropertySort)obj;}propertyGrid1.Paint -= new PaintEventHSEO靠我andler(propertyGrid1_Paint);propertyGrid1.CollapseAllGridItems(); }

七、 闪屏问题

Form.DoubleBuffereSEO靠我d = true; 或者 SetStyle(ControlStyles.OptimizedDoubleBuffer, true);

八、 主要参考

充分利用 .NET Framework PropertySEO靠我Grid 控件 | Microsoft Learn

c# PropertyGrid 自定义属性排序_楚楚3107的博客-CSDN博客

PropertyGrid控件 分类(Category)及属性(PropSEO靠我erty)排序_propertygrid 排序_衣舞晨风的博客-CSDN博客

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2