C# Winform PropertyGrid显示中文

news/2024/12/22 20:02:43/

主要原理是在枚举上添加DescriptionAttribute属性,然后通过反射将其显示出来

方法1:继承StringConverter类

public class EnumConvertor : StringConverter
{public override bool GetStandardValuesSupported(ITypeDescriptorContext context){return true;}public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value){if (!(value is string)) return base.ConvertFrom(context, culture, value);var type = context.GetValue<Type>("PropertyType");var field = type?.GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(f =>{if (!(f.GetCustomAttribute(typeof(DescriptionAttribute)) is DescriptionAttribute description)) return false;return description.Description.Equals(value.ToString());});if (type != null && field != null)return Enum.Parse(type, field.Name);return base.ConvertFrom(context, culture, value);}public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType){// 将Enum类型转换成string进行显示if (destinationType != typeof(string)) return base.ConvertTo(context, culture, value, destinationType);var type = context.GetValue<Type>("PropertyType");var field = type?.GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(f => f.Name.Equals(value.ToString()));if (field != null && field.GetCustomAttribute(typeof(DescriptionAttribute)) is DescriptionAttribute description)return description.Description;return base.ConvertTo(context, culture, value, destinationType);}public override StandardValuesCollectionGetStandardValues(ITypeDescriptorContext context){List<string> list = new List<string>();var type = context.GetValue<Type>("PropertyType");foreach (var info in type.GetFields(BindingFlags.Public | BindingFlags.Static)){if (!(info.GetCustomAttribute(typeof(DescriptionAttribute)) is DescriptionAttribute description))continue;list.Add(description.Description);}return new StandardValuesCollection(list);}
}

方法2:自定义界面显示

public class EnumEditor : UITypeEditor
{private class EnumItem{public object Value { get; set; }public string Name { get; set; }}public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context){return UITypeEditorEditStyle.DropDown;}public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value){bool cancel;if (provider == null) return value;if (!(provider.GetService(typeof(IWindowsFormsEditorService)) is IWindowsFormsEditorService editorService))return value;ListBox listBox = new ListBox{DisplayMember = "Name",// 这里需要将DrawMode设置成OwnerDrawVariable才可以设置ItemHeightDrawMode = DrawMode.OwnerDrawVariable,//IntegralHeight = true,Font = provider.GetValue<PropertyGrid>("OwnerGrid").Font,SelectionMode = SelectionMode.One};listBox.DrawItem += (sender, args) =>{args.DrawBackground();args.DrawFocusRectangle();StringFormat strFmt = new StringFormat();// 文本水平居中// strFmt.Alignment = StringAlignment.Center;// 文本垂直居中(根据需求进行设置)strFmt.LineAlignment = StringAlignment.Center; args.Graphics.DrawString((listBox.Items[args.Index] as EnumItem)?.Name, args.Font,new SolidBrush(args.ForeColor), args.Bounds, strFmt);};listBox.MouseClick += (sender, args) =>{int index = ((ListBox)sender).IndexFromPoint(args.Location);if (index < 0) return;editorService.CloseDropDown();};listBox.KeyDown += (sender, args) =>{if (args.KeyCode != Keys.Enter) return;editorService.CloseDropDown();};listBox.PreviewKeyDown += (sender, args) =>{if (args.KeyCode != Keys.Escape) return;cancel = true;editorService.CloseDropDown();};if (value != null){Type enumType = value.GetType();if (!enumType.IsEnum) throw new InvalidOperationException();foreach (FieldInfo fi in enumType.GetFields(BindingFlags.Public | BindingFlags.Static)){EnumItem item = new EnumItem{Value = fi.GetValue(null)};object[] attributes = fi.GetCustomAttributes(typeof(DescriptionAttribute), true);item.Name = attributes.Length > 0? (attributes[0] as DescriptionAttribute)?.Description: fi.Name;int index = listBox.Items.Add(item);if (fi.Name == value.ToString())listBox.SetSelected(index, true);}}listBox.ItemHeight += 6;// 设置列表显示的高度listBox.Height = listBox.ItemHeight * listBox.Items.Count + 3;cancel = false;editorService.DropDownControl(listBox);return cancel || listBox.SelectedIndices.Count == 0 ? value : (listBox.SelectedItem as EnumItem)?.Value;}
}public class EnumConverter : TypeConverter
{public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType){return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);}public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value){if (!(value is string)) return base.ConvertFrom(context, culture, value);var type = context.GetValue<Type>("PropertyType");var field = type?.GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(f =>{if (!(f.GetCustomAttribute(typeof(DescriptionAttribute)) is DescriptionAttribute description)) return false;return description.Description.Equals(value.ToString());});if (type != null && field != null)return Enum.Parse(type, field.Name);return base.ConvertFrom(context, culture, value);}public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType){return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);}public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value,Type destinationType){// 将Enum类型转换成string进行显示if (destinationType != typeof(string)) return base.ConvertTo(context, culture, value, destinationType);var type = context.GetValue<Type>("PropertyType");var field = type?.GetFields(BindingFlags.Public | BindingFlags.Static).FirstOrDefault(f => f.Name.Equals(value.ToString()));if (field != null && field.GetCustomAttribute(typeof(DescriptionAttribute)) is DescriptionAttribute description)return description.Description;return base.ConvertTo(context, culture, value, destinationType);}
}

使用

[Editor(typeof(EnumEditor), typeof(UITypeEditor)),TypeConverter(typeof(Forms.Utility.EnumConverter))]
public enum Alignment
{[Description("无")]None,[Description("居左")]Left,[Description("居中")]Center,[Description("居右")]Right
}

http://www.ppmy.cn/news/1474089.html

相关文章

Android SurfaceFlinger——创建EGLSurface(二十三)

我们知道 EGL 就是适配 Android 本地窗口系统和 OpenGL ES 的桥接层,OpenGL ES 定义了平台无关的 GL 绘图指令,EGL 则定义了控制 Displays、Contexts 以及 Surfaces 的统一的平台接口。前面我们已经介绍了 Surface 的相关内容,而对于 EGL 来说同样存在一个与之对应的 Surfac…

2005-2023年各省居民人均消费支出、城镇居民人均消费支出、农村居民人均消费支出数据(无缺失)

2005-2023年各省居民人均消费支出、城镇居民人均消费支出、农村居民人均消费支出数据&#xff08;无缺失&#xff09; 1、时间&#xff1a;2005-2023年 2、来源&#xff1a;国家统计局、统计年鉴 3、范围&#xff1a;31省 4、指标&#xff1a;全体居民人均消费支出、城镇居…

【深度学习练习】心脏病预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、什么是RNN RNN与传统神经网络最大的区别在于&#xff0c;每次都会将前一次的输出结果&#xff0c;带到下一隐藏层中一起训练。如下图所示&#xff1a; …

嵌入式C语言面试相关知识——编译过程

嵌入式C语言面试相关知识——编译过程 一、博客声明二、自问题目1、C语言的编译过程是什么&#xff1f;2、编译过程中参与的工具有哪些&#xff1f;3、什么是条件编译&#xff0c;作用是什么&#xff1f;4、链接环节中的静态链接和动态链接是什么&#xff0c;有何区别&#xff…

Cortex-A510——内核及汇编

Cortex-A510——内核及汇编 小狼http://blog.csdn.net/xiaolangyangyang 1、异常等级 2、异常等级切换 同步异常&#xff1a; 1、SVC/HVC/SMC&#xff1b; 2、MMU引发的异常&#xff08;内核态EL1发生&#xff0c;发生后不会进行异常等级切换…

智能井盖采集装置 开启井下安全新篇章

在现代城市的脉络之下&#xff0c;错综复杂的管网系统如同城市的血管&#xff0c;默默支撑着日常生活的有序进行。而管网的监测设备大多都安装在井下&#xff0c;如何给设备供电一直是一个难题&#xff0c;选用市电供电需经过多方审批&#xff0c;选用电池供电需要更换电池包&a…

鸿蒙NEXT

鸿蒙NEXT&#xff1a;华为操作系统的新篇章 随着华为鸿蒙生态千帆启航仪式的圆满举行&#xff0c;标志着鸿蒙原生应用开发正式进入一个新的阶段。作为对技术保持敏感的程序员&#xff0c;我们有必要深入了解这一全新操作系统HarmonyOS NEXT的技术细节和未来发展方向。 首先引…

科普文:微服务之服务网格Service Mesh

一、ServiceMesh概念 背景 随着业务的发展&#xff0c;传统单体应用的问题越来越严重&#xff1a; 单体应用代码库庞大&#xff0c;不易于理解和修改持续部署困难&#xff0c;由于单体应用各组件间依赖性强&#xff0c;只要其中任何一个组件发生更改&#xff0c;将重新部署整…