以基本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(); } } }
问题和重现步骤:
-
当我在设计器中打开Form1时,属性处于以下状态。
状态:ControlChecked = False – ControlVisible = True (粗体)
ControlVisible按预期设置为True ,但它是粗体。 [DefaultValueAttribute]在基本表单中设置为true ,因此我希望此属性不以粗体显示。
-
我现在在设计器中将ControlVisible更改为False 。 大胆的关闭。
状态:ControlChecked = False – ControlVisible = False
-
我现在重建项目,并重新生成Form 1中的代码。 ControlVisible属性以粗体还原为True 。
状态:ControlChecked = False – ControlVisible = True (粗体)
-
我现在将ControlChecked从False更改为True ,并按预期变为粗体。
状态:ControlChecked = True (粗体) – ControlVisible = True (粗体)
-
我重建项目并没有改变。
状态:ControlChecked = True (粗体) – ControlVisible = True (粗体)
-
我现在将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上面的BaseForm
, TestPropery
行为与示例中的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;