以基本forms定义的自定义属性在重建时会以inheritance的forms丢失其状态

我在使用基本forms的属性时遇到问题,而这些属性没有以inheritance的forms维护状态。

环境:

  • Visual Studio 2010 Ultimate Service Pack 1:版本10.0.40219.1 SP1Rel
  • .Net Framework:版本4.0.30319 SP1Rel
  • Windows 7旗舰版

下面是重现的源代码和步骤:

using System; using System.ComponentModel; using System.Windows.Forms; namespace Test { public partial class BaseForm : Form { [DefaultValueAttribute(true)] public bool ControlVisible { get { return this.checkBox1.Visible; } set { this.checkBox1.Visible = value; } } [DefaultValueAttribute(false)] public bool ControlChecked { get { return this.checkBox1.Checked; } set { this.checkBox1.Checked = value; } } public BaseForm() { InitializeComponent(); } } } 

在上面,默认属性与[DefaultValueAttribute]匹配,即在InitializeComponent()中,checkBox1.Visible设置为true,checkBox1.Checked为false。 这些是放在表单上时控件的默认设置。

然后我创建了以下inheritance的表单:

 using System; using System.ComponentModel; using System.Windows.Forms; namespace Test { public partial class Form1 : BaseForm { public Form1() { InitializeComponent(); } } } 

问题和重现步骤:

  1. 当我在设计器中打开Form1时,属性处于以下状态。

    状态:ControlChecked = False – ControlVisible = True (粗体)

    ControlVisible按预期设置为True ,但它是粗体。 [DefaultValueAttribute]在基本表单中设置为true ,因此我希望此属性不以粗体显示。

  2. 我现在在设计器中将ControlVisible更改为False 。 大胆的关闭。

    状态:ControlChecked = False – ControlVisible = False

  3. 我现在重建项目,并重新生成Form 1中的代码。 ControlVisible属性以粗体还原为True

    状态:ControlChecked = False – ControlVisible = True (粗体)

  4. 我现在将ControlCheckedFalse更改为True ,并按预期变为粗体。

    状态:ControlChecked = True (粗体) – ControlVisible = True (粗体)

  5. 我重建项目并没有改变。

    状态:ControlChecked = True (粗体) – ControlVisible = True (粗体)

  6. 我现在将ControlVisible的属性从True更改为False并再次重建项目。 ControlVisible以粗体显示回到True

    状态:ControlChecked = True (粗体) – ControlVisible = True (粗体)

ControlChecked似乎按预期工作。 当ControlVisible设置为false并且反转粗体时,它会一直翻转回True 。 在我看来,基础表单中的[DefaultAttributeValue]为true无法识别。

更新:修改以修复错误,更准确地隔离问题。

更新:如果我在BaseForm的构造函数中设置checkBox1.Visible = false,那么一切都按预期工作。 因此,最重要的是,似乎问题是在inheritance的表单中的自定义属性上识别为DefaultValueAttribute为true

你的checkBox1在基类中是私有的吗? 如果它不是那么它应该是,因为设计者将序列化两个setter(一个用于checkBox1.Visible而另一个用于ControlVisible),并且只有序列化的顺序将决定最终状态,这是不好的。

另外,查看Form1.designer.cs文件中的自动生成的InitializeControls方法,是否将自定义属性显式设置为默认值?

最后,尝试使用ShouldSerialze和Reset ,看看你是否有不同的行为。

编辑

我在本地重新创建了问题,并附加了一个VS实例来调试另一个。 第一次由VS评估属性ControlVisible时,它返回false因为checkBox1.Visible (getter源)为false 。 当创建并显示实际的复选框控件,并且滚动属性窗口以显示ControlVisible它的值再次被评估,并且它返回true ,这是默认值,但是似乎VS内部已经标记了该属性被修改,因为它是初始的值与默认值不同。 这可能是VS中的一个错误。

我创建了一个简单的效果演示:

  public BaseForm() { InitializeComponent(); _testValue = false; } private bool _testValue; [DefaultValue(true)] public bool TestProperty { get { return _testValue; } set { _testValue = value; } } protected override void OnVisibleChanged(EventArgs e) { _testValue = true; base.OnVisibleChanged(e); } } 

inheritance上面的BaseFormTestPropery行为与示例中的ControlVisible完全相同,所以我认为这是VS中的一个错误。

你的问题的解决方案是使用一个简单的bool支持字段作为帮助,因为checkBox1.Visible是不可靠的:

  public BaseForm() { InitializeComponent(); checkBox1.Visible = _controlVisible = true; } private bool _controlVisible; [DefaultValue(true)] public bool ControlVisible { get { return _controlVisible; } set { _controlVisible = checkBox1.Visible = value; } } 

您的ControlVisible属性始终设置为false:

  [DefaultValueAttribute(true)] public bool ControlVisible { get { return this.checkBox1.Visible; } set { this.checkBox1.Visible = false; } } 

你的set方法应该是:

  this.checkBox1.Visible = value;