【问题标题】:Property Grid Number formatting属性网格编号格式
【发布时间】:2013-05-08 14:54:14
【问题描述】:

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

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

例如,我希望它在网格中显示为 1.000.000。

这有一些属性吗?

【问题讨论】:

  • 这看起来应该是三个属性,即major、minor、revision。如果可能的话,您将需要编写自己的格式化程序,如 String.Format
  • OP 使用欧洲编号方案,千位分隔符是.,而不是像美国那样的,。所以这个问题Version格式有关,而是与数字格式有关。

标签: c# winforms propertygrid


【解决方案1】:

您应该为您的整数属性实现自定义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 的工作原理以及如何对其进行自定义。

【讨论】:

  • 作为一个有趣的调整,参数context.Instance 指向正在显示的对象,如果存在任何格式线索(如格式字符串属性),您可以在ToString() 中使用它们。跨度>
  • 注意,这个例子是特定于int的,不会处理比如long。
【解决方案2】:

我不知道直接在 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(".", ""));
        }
    }
}

PropertyGrid 中仅显示Browsable(true) 属性。

【讨论】:

  • 这实际上是我的首选解决方案,因为它提供了定制级别。
【解决方案3】:

我有同样的问题,并提出了一个比 Sergy 的答案更灵活的解决方案。它涉及 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 的任何类型来使其在某种程度上独立于类型,但我不会对此进行深入探讨。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 2011-05-21
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多