C# 当用户控件在公共属性上具有 Browsable false 时,为什么设计器在添加到表单时将其设置为 null?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/889424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When a user control has Browsable false on public property, why does designer set it to null when added to a form?
提问by Jeff
I have a user control that has a few public properties, one is an object where I set [Browseable(false)]. When I add this control in Visual Studio's designer the generated code sets this object to null.
我有一个用户控件,它有一些公共属性,一个是我设置 [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;
...
}
I don't understand why Visual Studio would want to do that and I'm curious if there is a way to mark it so that it doesn't set it. I discovered this by setting the object to something in the constructor only to watch the contol's parent set it back to null.
我不明白为什么 Visual Studio 想要这样做,我很好奇是否有办法标记它以便它不会设置它。我通过在构造函数中将对象设置为某些东西来发现这一点,只是为了观察控制的父级将其设置回 null。
采纳答案by David Nelson
There are a couple of options here. First, BrowsableAttribute only determines whether the property shows up in the property grid. To prevent the property from being serialized at all, use the DesignerSerializationVisibilityAttribute:
这里有几个选项。首先, BrowsableAttribute 仅确定属性是否显示在属性网格中。要完全防止属性被序列化,请使用 DesignerSerializationVisibilityAttribute:
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public object Bar { get; set; }
Second, if you want the property to be serialized, but only when the user has actually changed the value, use the DefaultValueAttribute:
其次,如果您希望属性被序列化,但仅当用户实际更改了值时,请使用 DefaultValueAttribute:
[Browsable(true)]
[DefaultValue(false)]
public bool IsSomething { get; set; }
This will cause the property to only be serialized if it is different from its default value. This also has other positive side-effects
这将导致该属性仅在与其默认值不同时才被序列化。这也有其他积极的副作用
- The property value is shown in a normal font when it has not been changed, but in bold when it has been changed.
- The "Reset" option will be available when right-clicking the property in the property grid.
- 属性值未更改时以普通字体显示,更改后以粗体显示。
- 右键单击属性网格中的属性时,“重置”选项将可用。
There are more advanced techniques for controlling property interaction with the designer (Google "ShouldSerialize"), but these attributes should get you most of the way there.
有更高级的技术来控制与设计器的属性交互(谷歌“ShouldSerialize”),但这些属性应该可以帮助您完成大部分工作。
回答by BFree
Generally, when you set values in the constructor of your custom control, the VS designer will generate code that sets all those values that you're setting in the constructor. IE:
通常,当您在自定义控件的构造函数中设置值时,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; }
}
When I add a MyTextBox to my Form, this is the generated code:
当我将 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;
The catch here is though, that if you make changes to your constructor, you need to rebuild the project and in many cases remove the control from the form and re-add it so that VS can regenerate the code. I'm guessing that in your case VS just hasn't caught up to your changes. Try removing the control from the form and rebuilding the control. Then re-add it, and it shouldwork.
但这里的问题是,如果对构造函数进行更改,则需要重新构建项目,并且在许多情况下从表单中删除控件并重新添加它,以便 VS 可以重新生成代码。我猜在你的情况下 VS 只是没有赶上你的变化。尝试从窗体中删除控件并重建控件。然后重新添加它,它应该可以工作。