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