Подтвердить что ты не робот

Когда пользовательский элемент управления имеет видимое значение Openable в общедоступном свойстве, почему дизайнер добавляет его в null при добавлении в форму?

У меня есть пользовательский элемент управления, который имеет несколько общедоступных свойств, один из которых является объектом, где я устанавливаю [Доступный (false)]. Когда я добавляю этот элемент управления в конструктор Visual Studio, сгенерированный код устанавливает для этого объекта значение null.

public class Foo : System.Windows.Forms.UserControl
{
    [Browsable(false)]
    public object Bar { get; set; }

    [Browsable(true)]
    public bool IsSomething { get; set; }

    ...
}

private void InitializeComponent()
{
    ...
    this.foo = new Foo();

    this.foo.IsSomething = false;
    this.foo.Bar = null;
    ...
}

Я не понимаю, почему Visual Studio захочет это сделать, и мне любопытно, есть ли способ отметить его, чтобы он не устанавливал его. Я обнаружил это, установив объект на что-то в конструкторе только для того, чтобы посмотреть, что родитель contol вернул его в нуль.

4b9b3361

Ответ 1

Здесь есть пара вариантов. Во-первых, BrowsableAttribute определяет только, появляется ли свойство в сетке свойств. Чтобы свойство вообще не было сериализовано, используйте атрибут DesignerSerializationVisibilityAttribute:

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Bar { get; set; }

Во-вторых, если вы хотите, чтобы свойство было сериализовано, но только когда пользователь действительно изменил значение, используйте DefaultValueAttribute:

[Browsable(true)]
[DefaultValue(false)]
public bool IsSomething { get; set; }

Это приведет к тому, что свойство будет только сериализовано, если оно отличается от значения по умолчанию. Это также имеет другие положительные побочные эффекты.

  • Значение свойства отображается обычным шрифтом, если он не был изменен, но выделен жирным шрифтом, когда он был изменен.
  • Опция "Reset" будет доступна при щелчке правой кнопкой мыши по свойству в сетке свойств.

Существуют более продвинутые методы управления взаимодействием свойств с дизайнером (Google "ShouldSerialize" ), но эти атрибуты должны получить от вас большую часть пути.

Ответ 2

Обычно, когда вы устанавливаете значения в конструкторе вашего настраиваемого элемента управления, конструктор VS будет генерировать код, который устанавливает все те значения, которые вы устанавливаете в конструкторе. IE:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
}

public class MyTextBox : TextBox
{
    public MyTextBox()
    {
        this.Person = new Person
        {
            FirstName = "John",
            LastName = "Doe",
            Age = 45
        };
    }


    [Browsable(false)]
    public Person Person { get; set; }
}

Когда я добавляю MyTextBox в свою форму, это сгенерированный код:

// 
// myTextBox1
// 
this.myTextBox1.Location = new System.Drawing.Point(149, 91);
this.myTextBox1.Name = "myTextBox1";
person1.Age = 45;
person1.FirstName = "John";
person1.LastName = "Doe";
this.myTextBox1.Person = person1;
this.myTextBox1.Size = new System.Drawing.Size(100, 20);
this.myTextBox1.TabIndex = 3;

Ловушка здесь, однако, что если вы вносите изменения в свой конструктор, вам нужно перестроить проект и во многих случаях удалить элемент управления из формы и повторно добавить его, чтобы VS мог восстановить код. Я предполагаю, что в вашем случае VS просто не догнал ваши изменения. Попробуйте удалить элемент управления из формы и перестроить элемент управления. Затем повторно добавьте его, и он должен работать.