C# 当用户控件在公共属性上具有Browsable false时,为什么设计器在添加到窗体时将其设置为null?

C# 当用户控件在公共属性上具有Browsable false时,为什么设计器在添加到窗体时将其设置为null?,c#,winforms,visual-studio-2008,user-controls,C#,Winforms,Visual Studio 2008,User Controls,我有一个用户控件,它有几个公共属性,其中一个是我设置[Browseable(false)]的对象。当我在VisualStudio的设计器中添加此控件时,生成的代码将此对象设置为null public class Foo : System.Windows.Forms.UserControl { [Browsable(false)] public object Bar { get; set; } [Browsable(true)] public bool IsSom

我有一个用户控件,它有几个公共属性,其中一个是我设置[Browseable(false)]的对象。当我在VisualStudio的设计器中添加此控件时,生成的代码将此对象设置为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;
    ...
}

我不明白为什么VisualStudio会想这么做,我很好奇是否有一种方法可以标记它,这样它就不会设置它。我发现这一点是通过将对象设置为构造函数中的某个对象,只是为了观察控件的父对象将其设置回null

通常,当您在自定义控件的构造函数中设置值时,VS设计器将生成代码来设置您在构造函数中设置的所有值。即:

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没有跟上你的变化。尝试从窗体中删除该控件并重新生成该控件。然后重新添加它,它应该会工作。

这里有几个选项。首先,BrowsableAttribute仅确定属性是否显示在属性网格中。要完全防止序列化属性,请使用DesignerSerializationVisibilityAttribute:

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Bar { get; set; }
[Browsable(true)]
[DefaultValue(false)]
public bool IsSomething { get; set; }
其次,如果希望序列化属性,但仅当用户实际更改了值时,请使用DefaultValueAttribute:

[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Bar { get; set; }
[Browsable(true)]
[DefaultValue(false)]
public bool IsSomething { get; set; }
这将导致仅当属性与其默认值不同时才序列化该属性。这也有其他积极的副作用

  • 属性值未更改时以普通字体显示,更改后以粗体显示
  • 在属性网格中右键单击属性时,“重置”选项将可用

  • 有更先进的技术可以控制与设计器的属性交互(Google“ShouldSerialize”),但这些属性应该可以让您在大部分方面都做到这一点。

    谢谢您的回答。回到这个问题上花了一点时间,但是DesignerSerializationVisibility停止将控件设置为null。
    Browseable
    属性只是指定公共属性是否应在设计时显示在
    属性窗口中。因此,如果将其设置为
    false
    ,则应显示它。您的
    null
    值可能是由
    无重建
    情况引起的。