C# Winform PropertyGrid显示中文

主要原理是在枚举上添加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 StandardValuesCollection
        GetStandardValues(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才可以设置ItemHeight
            DrawMode = 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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值