简体   繁体   English

如何在 Windows 窗体设计器中保存用户控件的结构属性?

[英]How to save a struct property of a user control in Windows Forms Designer?

I've checked the answers of this question: Modifying structure property in a PropertyGrid我已经检查了这个问题的答案: Modifying structure property in a PropertyGrid

And also SizeConverter from .net.还有来自 .net 的SizeConverter

But not helpful, my property is still not saved.但没有帮助,我的财产仍然没有保存。


I have a struct, a user control, and a custom type converter.我有一个结构体、一个用户控件和一个自定义类型转换器。

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();
    }
}

After compile, I drag the control in a form then I can see the property Bar.Text showed in the properties window, I also can edit the value and it seems be saved.编译后,我将控件拖到一个窗体中,然后我可以在属性窗口中看到属性Bar.Text ,我也可以编辑该值,它似乎被保存了。


But nothing is generated in the InitializeComponent method但是InitializeComponent方法中没有生成任何内容

什么也没有产生

So if I reopen the designer, the Text field in the properties window become empty.因此,如果我重新打开设计器,属性窗口中的文本字段将变为空。

Please notice the struct hasn't a custom constructor, so I cannot use InstanceDescriptor .请注意该结构没有自定义构造函数,所以我不能使用InstanceDescriptor

Do I miss any important steps?我错过了任何重要的步骤吗?

You are missing a few method overrides in the type descriptor:您在类型描述符中缺少一些方法覆盖:

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;
    }
}

And add constructor to the struct:并将构造函数添加到结构中:

[TypeConverter(typeof(BarConverter))]
public struct Bar
{
    public Bar(string text)
    {
        Text = text;
    }
    public string Text { get; set; }
}

And this is how the Bar property serializes:这就是Bar属性序列化的方式:

// 
// userControl11
// 
this.userControl11.Bar = new SampleWinApp.Bar("Something");

And the bar property will be shown like following image in property grid, having Text property editable: bar 属性将在属性网格中显示如下图,具有可编辑的Text属性:

在此处输入图片说明

You may also want to provide a better string representation for the struct by overriding its ToString() method of the struct, and also make the property convertible from string in property grid, by overriding CanConvertFrom and ConvertFrom like PointConverter or SizeConverter .您可能还想通过覆盖结构的ToString()方法为结构提供更好的字符串表示,并通过覆盖CanConvertFromConvertFromPointConverterSizeConverter一样使属性可从属性网格中的字符串转换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM