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

2

Я проверил ответы на этот вопрос: изменение свойства структуры в 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

Изображение 174551

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

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

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

  • 2
    @MindSwipe не могли бы вы прочитать вопрос до голосования?
  • 0
    Я сделал,> «Но ничего не генерируется в методе InitializeComponent», затем приходит изображение, почему бы просто не опубликовать код? Если вы прошли через скриншот и загрузку изображения, почему бы просто не нажать Ctrl + C, Ctrl + V? Я вижу первую часть, где вы разместили код, но зачем сдаваться на полпути?
Показать ещё 4 комментария
Теги:
struct
winforms
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:

Изображение 174551

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

  • 0
    Структура не имеет конструктора, поэтому я должен добавить его?
  • 0
    Да, так и должно быть.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню