WinForms 属性网格不允许我更改结构值
不太确定为什么会发生这种情况,但我希望能够修改 XNA 颜色值:
private Color _color = Color.White;
[System.ComponentModel.Category("VisibleInEditor")]
[System.ComponentModel.TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public Color Color
{
get { return _color; }
set { _color = value; }
}
我认为拥有 ExpandableObjectConverter 属性可以解决问题,但它尚未这样做。
编辑:我能够将以下工作代码修补在一起:
public class ColorTypeConverter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType)
{
return destinationType == typeof(Color);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType)
{
if (destinationType == typeof(string) && value is Color)
{
Color color = (Color)value;
return string.Format("{0}, {1}, {2}, {3}", color.R, color.G, color.B, color.A);
}
else return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
try
{
string strVal = value as string;
var parts = strVal.Split(',');
byte r = byte.Parse(parts[0]);
byte g = byte.Parse(parts[1]);
byte b = byte.Parse(parts[2]);
byte a = byte.Parse(parts[3]);
return new Color(r, g, b, a);
}
catch
{
throw new ArgumentException("Can not convert '" + (string)value + "'to type Color");
}
}
else return base.ConvertFrom(context, culture, value);
}
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
{
return new Color((byte)propertyValues["R"], (byte)propertyValues["G"], (byte)propertyValues["B"], (byte)propertyValues["A"]);
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value, attributes);
string[] sortOrder = new string[4];
sortOrder[0] = "R";
sortOrder[1] = "G";
sortOrder[2] = "B";
sortOrder[3] = "A";
// Return a sorted list of properties
return properties.Sort(sortOrder);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}
Not quite sure why this is happening, but I want to be able to modify the XNA color value:
private Color _color = Color.White;
[System.ComponentModel.Category("VisibleInEditor")]
[System.ComponentModel.TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))]
public Color Color
{
get { return _color; }
set { _color = value; }
}
I thought having the ExpandableObjectConverter attribute would fix the issue, but it has not yet done so.
Edit: I was able to patch together the following working code:
public class ColorTypeConverter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType)
{
return destinationType == typeof(Color);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType)
{
if (destinationType == typeof(string) && value is Color)
{
Color color = (Color)value;
return string.Format("{0}, {1}, {2}, {3}", color.R, color.G, color.B, color.A);
}
else return base.ConvertTo(context, culture, value, destinationType);
}
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
return sourceType == typeof(string);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
try
{
string strVal = value as string;
var parts = strVal.Split(',');
byte r = byte.Parse(parts[0]);
byte g = byte.Parse(parts[1]);
byte b = byte.Parse(parts[2]);
byte a = byte.Parse(parts[3]);
return new Color(r, g, b, a);
}
catch
{
throw new ArgumentException("Can not convert '" + (string)value + "'to type Color");
}
}
else return base.ConvertFrom(context, culture, value);
}
public override object CreateInstance(ITypeDescriptorContext context, System.Collections.IDictionary propertyValues)
{
return new Color((byte)propertyValues["R"], (byte)propertyValues["G"], (byte)propertyValues["B"], (byte)propertyValues["A"]);
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value, attributes);
string[] sortOrder = new string[4];
sortOrder[0] = "R";
sortOrder[1] = "G";
sortOrder[2] = "B";
sortOrder[3] = "A";
// Return a sorted list of properties
return properties.Sort(sortOrder);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
ExpandableConverter 将仅显示 Color 的内部属性。您将无法编辑 R、G、B 和 A,因为它们只有 get 访问器。使用 ColorConverter 也不会显示这些属性,因此这不是解决方案。您将需要编写自己的转换器。例如,使用 Reflector 并查看 FontConverter。您将看到如何使用 CreateInstance 从其属性构建新的颜色。
ExpandableConverter will just show the inner properties of a Color. You won't be able to edit R, G, B and A since they only have get accessors. Using ColorConverter won't show you these properties either so this is not a solution. You will need to write your own converter. Use Reflector and have a look at FontConverter for example. You will see how CreateInstance can be used to build a new Color from its properties.