我已经检查了这个问题的答案:Modifying structure property in a PropertyGrid
还有来自.net的SizeConverter
。
但没有帮助,我的财产仍然没有保存。
我有一个结构,一个用户控件和一个自定义类型转换器。
public partial class UserControl1 : UserControl
{
public Bar bar { get; set; } = new Bar();
}
[TypeConverter(typeof(BarConverter))]
public struct Bar
{
public string Text { get; set; }
}
public class BarConverter : ExpandableObjectConverter
{
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues != null && propertyValues.Contains("Text"))
return new Bar { Text = (string)propertyValues["Text"] };
return new Bar();
}
}
编译后,我在一个窗体中拖动控件,然后我可以看到属性窗口中显示属性Bar.Text
,我也可以编辑值,它似乎被保存。
但是在InitializeComponent
方法中没有生成任何东西
因此,如果我重新打开设计器,属性窗口中的Text字段将变为空。
请注意结构没有自定义构造函数,所以我不能使用InstanceDescriptor
。
我是否会错过任何重要的步骤?
您在类型描述符中缺少一些方法覆盖:
public class BarConverter : ExpandableObjectConverter
{
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
return true;
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
ConstructorInfo ci = typeof(Bar).GetConstructor(new Type[] { typeof(string) });
Bar t = (Bar)value;
return new InstanceDescriptor(ci, new object[] { t.Text });
}
return base.ConvertTo(context, culture, value, destinationType);
}
public override object CreateInstance(ITypeDescriptorContext context,
IDictionary propertyValues)
{
if (propertyValues == null)
throw new ArgumentNullException("propertyValues");
object text = propertyValues["Text"];
return new Bar((string)text);
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
}
并将构造函数添加到结构中:
[TypeConverter(typeof(BarConverter))]
public struct Bar
{
public Bar(string text)
{
Text = text;
}
public string Text { get; set; }
}
这就是Bar
属性序列化的方式:
//
// userControl11
//
this.userControl11.Bar = new SampleWinApp.Bar("Something");
bar属性将显示为属性网格中的以下图像,具有可编辑的Text
属性:
您可能还希望通过覆盖结构的ToString()
方法为结构提供更好的字符串表示形式,并通过重写CanConvertFrom
和ConvertFrom
(如PointConverter
或SizeConverter
)使属性可以从属性网格中的字符串转换。