Как сохранить свойство типа структуры пользовательского элемента управления в конструкторе winform? - PullRequest
2 голосов
/ 08 марта 2019

Я проверил ответы на этот вопрос: Изменение свойства структуры в PropertyGrid

А также SizeConverter от .net.

Но это не помогло, моя собственность все еще не сохранена.


У меня есть структура, пользовательский элемент управления и пользовательский преобразователь типов.

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

Поэтому, если я снова открою конструктор, поле Текст в окне свойств станет пустым.

Обратите внимание, что структура не имеет собственного конструктора, поэтому я не могу использовать InstanceDescriptor.

Я пропускаю какие-нибудь важные шаги?

1 Ответ

1 голос
/ 08 марта 2019

Вам не хватает нескольких переопределений методов в дескрипторе типа:

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

enter image description here

Вы также можете предоставить лучшее строковое представление для структуры, переопределив ее ToString() метод структуры, а также сделать свойство конвертируемым из строки в сетке свойств, переопределив CanConvertFrom и ConvertFrom like PointConverter или SizeConverter.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...