我检查了这个问题的答案: 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
方法中什么也没有产生
因此,如果我重新打开设计器,则属性窗口中的“文本”字段将变为空。
请注意,该结构没有自定义构造函数,因此我无法使用InstanceDescriptor
。
我错过任何重要的步骤吗?
答案 0 :(得分:1)
您在类型描述符中缺少一些方法覆盖:
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;
}
}
并将构造函数添加到struct中:
[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
和{ {1}},例如PointConverter
或SizeConverter
。