是否可以格式化在winforms的PropertyGrid中显示的数字属性?
class MyData
{
public int MyProp {get; set;}
}
我希望它在网格中显示为例如1.000.000。
这有什么属性吗?
答案 0 :(得分:13)
您应该为整数属性实现自定义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如何工作以及如何自定义。
答案 1 :(得分:7)
我不知道在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)
属性。
答案 2 :(得分:1)
我有同样的问题,并提出了一个比Sergy的回答稍微灵活的解决方案。它涉及TypeConverter和自定义属性。 TypeConverter负责执行转换,而custom属性则告诉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
查找提供{F1”格式字符串的FormattedDoubleFormatString
属性。
该属性很简单,它只接受并保存格式字符串:
[AttributeUsage(AttributeTargets.Property)]
class FormattedDoubleFormatString : Attribute
{
public string FormatString { get; private set; }
public FormattedDoubleFormatString(string formatString)
{
FormatString = formatString;
}
}
就在那里。可用于任何格式的解决方案。您甚至可以通过将其更改为转换实现IConvertable
的任何类型来使它在某种程度上与类型无关,但是我不会对此进行深入介绍。