Когда пользовательский элемент управления имеет значение Browsable false для открытого свойства, почему конструктор устанавливает его в null при добавлении в форму? - PullRequest
12 голосов
/ 20 мая 2009

У меня есть пользовательский элемент управления, имеющий несколько открытых свойств, один из которых - объект, для которого я установил [Browseable (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 захочет сделать это, и мне любопытно, есть ли способ пометить его, чтобы он не устанавливал его. Я обнаружил это, установив объект на что-то в конструкторе только для того, чтобы посмотреть, как родительский элемент управления установил для него значение null.

Ответы [ 2 ]

20 голосов
/ 20 мая 2009

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

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

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

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

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

  1. Значение свойства отображается обычным шрифтом, когда оно не было изменено, но жирным шрифтом, когда оно было изменено.
  2. Параметр «Сброс» будет доступен при щелчке правой кнопкой мыши свойства в сетке свойств.

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

2 голосов
/ 20 мая 2009

Обычно, когда вы устанавливаете значения в конструкторе вашего пользовательского элемента управления, конструктор 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 просто не догнал ваши изменения. Попробуйте удалить элемент управления из формы и перестроить его. Затем добавьте его снова, и оно должно работать.

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