如何在winform设计器中保存用户控件的struct type属性?

问题描述 投票:2回答:1

我已经检查了这个问题的答案: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方法中没有生成任何东西

nothing generated

因此,如果我重新打开设计器,属性窗口中的Text字段将变为空。

请注意结构没有自定义构造函数,所以我不能使用InstanceDescriptor

我是否会错过任何重要的步骤?

c# winforms struct windows-forms-designer
1个回答
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;
    }
}

并将构造函数添加到结构中:

[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属性:

enter image description here

您可能还希望通过覆盖结构的ToString()方法为结构提供更好的字符串表示形式,并通过重写CanConvertFromConvertFrom(如PointConverterSizeConverter)使属性可以从属性网格中的字符串转换。

© www.soinside.com 2019 - 2024. All rights reserved.