C# 重建用户控件时,用户控件自定义属性将丢失状态

C# 重建用户控件时,用户控件自定义属性将丢失状态,c#,winforms,user-controls,properties,custom-controls,C#,Winforms,User Controls,Properties,Custom Controls,我有一个自定义属性的用户控件,如下所示: [DefaultValue(true)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] [Description("Gets or sets whether the \"Remove\" button is visible.")] public bool ShowRemoveButton { get { return t

我有一个自定义属性的用户控件,如下所示:

[DefaultValue(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Description("Gets or sets whether the \"Remove\" button is visible.")]
public bool ShowRemoveButton
{
    get
    {
        return this.removeButton.Visible;
    }
    set
    {
        this.removeButton.Visible = value;
    }
}
该控件包含一个标准按钮控件。此属性用于显示或隐藏按钮。用户控件构建在单独的项目程序集中。我把它放在一个表格上,我可以设置和取消设置上面的属性,一切看起来都很好。但是,当重建包含用户控件的项目时,属性值将翻转为“false”,这不是默认值


重建控件时,如何防止自定义属性丢失/更改其状态?

问题在于
DefaultValueAttribute
仅告诉设计器属性的默认值。它控制属性是否显示为粗体,以及右键单击属性并从关联菜单中选择“重置”时重置的值

它没有做的是在运行时将属性设置为特定值。为此,您需要在用户控件的构造函数方法中放置代码。例如:

// set default visibility
this.removeButton.Visible = true;

否则,如前所述,重建项目时将重置该属性的值。它将在设计器的“属性”窗口中以粗体显示,因为它与默认值不匹配(如
DefaultValueAttribute
中指定的),但该属性不会更改值的设置。

一种防止任何包含控件的属性在(de)时重置的简单方法相关属性的序列化是使用属性的专用支持字段,并指定与
DefaultValue
属性参数匹配的默认值。在本例中,这是下面的声明/分配

[DefaultValue(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Description("Gets or sets whether the \"Remove\" button is visible.")]
public bool ShowRemoveButton
{
    get
    {
        return _showRemoveButton;
    }
    set
    {
        _showRemoveButton = value;
        this.removeButton.Visible = value;
    }
}
private bool _showRemoveButton = true;

这是一篇旧文章,但它引导我找到了解决问题的方法。我也有同样的理由,我的财产在重建时失去了状态。在我的例子中,属性本身就是一个类,它提供了一组布尔值

对我来说,解决的办法是改变设计师们对房产进行整理的方式

   [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public SomePropertyClass SomeProperty
{
    get { return _SomeProperty; }
    set { _SomeProperty = Value; }
}
通过使用DesignerSerializationVisibility.Content,您可以告诉设计器序列化属性类(SomePropertyClass中包含的my Boolean)的内容,而不是属性本身。我想另一种方法是使SomePropertyClass可序列化,但上面的方法实现起来更快

也许这对某人有帮助。
Sascha

我尝试了上述方法,并在用户控件的构造函数中设置了“this.removeButton.Visible=true”。最初,它似乎保持了它的状态。未经更改的重建不会更改属性值。但是,当我更改用户控件并重建它时,属性再次切换为“false”并变为粗体。这很烦人。@Elan:那么你的代码中肯定有什么东西改变了值。我已经创建了许多可重用的控件库和用户控件,但是我从来没有遇到过这个问题。在代码中进行搜索,查看是否在任何地方设置了
removeButton.Visible
属性。它可能隐藏在自动插入的
*.Designer.cs
文件中,您无法看到它。用户控件在构造函数中将属性设置为“true”。主窗体的designer.cs正在将代码生成的“ShowRemoveButton”属性设置为false。只有这两个地方。我删除了用户控件的属性声明中的[DefaultValue(true)]属性,希望将主窗体上的属性设置为“true”会导致该值保持不变。但是,当重新生成designer.cs类并将其替换为“false”时,“true”的属性值将丢失。我无法坚持“真实”值。这是在一些表单设计器更改和重建之后发生的。@ ELAN:如果您能可靠地复制这个问题,请考虑编辑您的问题以包含其他人需要的最小代码。我想我理解你的意思,但我以前在自己的使用中从未见过这种行为。我知道Visual Studio的设计师会在一些边缘案例中弄巧成拙,但我有兴趣尽可能多地调查这些案例。如果我可以自己复制它,我可以给你一个修复程序,或者向Microsoft提交一个bug报告,并链接到此处供其他人确认。谢谢,我将尝试隔离复制所需的最低代码量,并将其发布。我需要几天时间才能回复你。