如何在Windows Forms Designer中保存用户控件的struct属性? [英] How to save a struct property of a user control in Windows Forms Designer?

查看:63
本文介绍了如何在Windows Forms Designer中保存用户控件的struct属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我检查了这个问题的答案:

因此,如果我重新打开设计器,则属性窗口中的文本"字段将变为空.

请注意,该结构没有自定义构造函数,因此我不能使用 InstanceDescriptor .

我错过任何重要的步骤吗?

解决方案

您在类型描述符中缺少一些方法覆盖:

 公共类BarConverter:ExpandableObjectConverter{公共重写bool CanConvertTo(ITypeDescriptorContext上下文,类型destinationType){如果(destinationType == typeof(InstanceDescriptor))返回true;返回base.CanConvertTo(context,destinationType);}公共重写对象ConvertTo(ITypeDescriptorContext上下文,CultureInfo文化,对象值,类型destinationType){如果(destinationType == typeof(InstanceDescriptor)){ConstructorInfo ci = typeof(Bar).GetConstructor(new Type [] {typeof(string)});柱t =(柱)值;返回新的InstanceDescriptor(ci,new object [] {t.Text});}返回base.ConvertTo(上下文,区域性,值,destinationType);}公共重写对象CreateInstance(ITypeDescriptorContext上下文,IDictionary属性值){如果(propertyValues == null)抛出新的ArgumentNullException("propertyValues");对象文本= propertyValues ["Text"];返回新的Bar((string)text);}公共重写布尔GetCreateInstanceSupported(ITypeDescriptorContext上下文){返回true;}} 

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

  [TypeConverter(typeof(BarConverter))]公共结构栏{公共栏(字符串文本){文字=文字;}公共字符串Text {get;放;}} 

这是 Bar 属性序列化的方式:

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

bar属性将像下面的图像一样显示在属性网格中,其中 Text 属性是可编辑的:

您可能还想通过覆盖结构的 ToString()方法来为结构提供更好的字符串表示形式,并通过覆盖 CanConvertFrom ConvertFrom ,例如 PointConverter SizeConverter .

I've checked the answers of this question: Modifying structure property in a PropertyGrid

And also SizeConverter from .net.

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.


But nothing is generated in the InitializeComponent method

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.

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:

// 
// 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:

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.

这篇关于如何在Windows Forms Designer中保存用户控件的struct属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆