winforms 特性轴网编号格式

72qzrwbm  于 2023-01-31  发布在  其他
关注(0)|答案(4)|浏览(125)

是否可以格式化winforms的PropertyGrid中显示的数值属性?

class MyData
{
      public int MyProp {get; set;}
}

我希望它在网格中显示为1.000.000。
这有什么属性吗?

hyrbngr7

hyrbngr71#

应该为integer属性实现自定义type converter

class MyData
{
    [TypeConverter(typeof(CustomNumberTypeConverter))]
    public int MyProp { get; set; }
}

PropertyGrid使用TypeConverter将对象类型(本例中为整数)转换为字符串,并使用该字符串在网格中显示对象值。在编辑过程中,TypeConverter将对象类型从字符串转换回您的对象类型。
因此,你需要使用类型转换器,它应该能够将整数转换成带有千位分隔符的字符串,并将这样的字符串解析回整数:

public class CustomNumberTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, 
                                        Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, 
        CultureInfo culture, object value)
    {            
        if (value is string)
        {
            string s = (string)value;
            return Int32.Parse(s, NumberStyles.AllowThousands, culture);
        }

        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, 
        CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
            return ((int)value).ToString("N0", culture);

        return base.ConvertTo(context, culture, value, destinationType);
    }
}

结果:

propertyGrid.SelectedObject = new MyData { MyProp = 12345678 };

我建议您阅读Getting the Most Out of the .NET Framework PropertyGrid Control MSDN文章,以了解PropertyGrid的工作原理以及如何对其进行自定义。

x6h2sr28

x6h2sr282#

我不知道直接在PropertyGrid中设置属性格式的方法,但您可以执行如下操作

class MyData
{
    [Browsable(false)]
    public int _MyProp { get; set; }

    [Browsable(true)]
    public string MyProp
    {
        get
        {
             return _MyProp.ToString("#,##0");
        }
        set
        {
             _MyProp = int.Parse(value.Replace(".", ""));
        }
    }
}

只有Browsable(true)属性显示在属性网格中。

dtcbnfnu

dtcbnfnu3#

我也有同样的问题,我想出了一个比塞尔吉的答案稍微灵活一些的解决方案,它涉及到TypeConverter和自定义属性,TypeConverter负责执行转换,而自定义属性告诉TypeConverter您希望字符串如何格式化。
我声明的示例类如下所示:

class MyData
{
    [TypeConverter(typeof(FormattedDoubleConverter))]
    [FormattedDoubleFormatString("F3")]
    public double MyProp { get; set; }
}

类型转换器的实现方式如下:

class FormattedDoubleConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string) || sourceType == typeof(double);
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return destinationType == typeof(string) || destinationType == typeof(double);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
                                       object value)
    {
        if (value is double)
            return value;

        var str = value as string;
        if (str != null)
            return double.Parse(str);

        return null;
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
                                     object value, Type destinationType)
    {
        if (destinationType != typeof(string))
            return null;

        if (value is double)
        {
            var property = context.PropertyDescriptor;
            if (property != null)
            {
                // Analyze the property for a second attribute that gives the format string
                var formatStrAttr = property.Attributes.OfType<FormattedDoubleFormatString>().FirstOrDefault();
                if (formatStrAttr != null)
                    return ((double)value).ToString(formatStrAttr.FormatString);
                else
                    return ((double)value).ToString();
            }
        }

        return null;
    }
}

注意,TypeConverter使用context.PropertyDescriptor来查找提供“F3”格式字符串的FormattedDoubleFormatString属性。
该属性很简单,它只接受并保存格式字符串:

[AttributeUsage(AttributeTargets.Property)]
class FormattedDoubleFormatString : Attribute
{
    public string FormatString { get; private set; }

    public FormattedDoubleFormatString(string formatString)
    {
        FormatString = formatString;
    }
}

这就是它,一个可以重用于任何格式的解决方案,你甚至可以通过改变它来转换任何实现IConvertable的类型,使它在某种程度上独立于类型,但是我不打算深入讨论这个问题。

lb3vh1jj

lb3vh1jj4#

我刚从约翰·索伊茨提供的代码中做了一个C#10版本。如果你觉得这个有用的话,请给予他一个赞成票!🤗
没有功能差异,它只是使用了开关表达式和空性检查。

using System.ComponentModel;
using System.Globalization;

namespace Roche.FOM.UI;

class FormattedDoubleConverter : TypeConverter {
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) {
        return sourceType == typeof(string) || sourceType == typeof(double);
    }

    public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) {
        return destinationType == typeof(string) || destinationType == typeof(double);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture,
        object?                                                 value) {
        return value switch {
            double     => value,
            string str => double.Parse(str),
            _          => null
        };
    }

    public override object? ConvertTo(
        ITypeDescriptorContext? context,
        CultureInfo?            culture,
        object?                 value, Type destinationType) {
        switch (value) {
            case double d when context != null && destinationType == typeof(string):
                var property      = context.PropertyDescriptor;
                var formatStrAttr = property.Attributes.OfType<FormattedDoubleFormatString>().FirstOrDefault();
                return formatStrAttr != null
                    ? d.ToString(formatStrAttr.FormatString)
                    : d.ToString(CultureInfo.CurrentCulture);
            default:
                return null;
        }
    }
}

相关问题