我遇到了基本表单的属性无法在继承的表单中维持状态的麻烦。
环境:
下面是复制的源代码和步骤:
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。这些是放置在表单上时控件的默认设置。
然后,我创建了以下继承形式:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : BaseForm
{
public Form1()
{
InitializeComponent();
}
}
}
问题和重现步骤:
状态:ControlChecked = False-ControlVisible = 真(粗体)
ControlVisible设置为True,如预期的那样,但是它是粗体。 [DefaultValueAttribute]在基本形式中设置为true,因此,我希望此属性不会以粗体显示。
状态:ControlChecked = False-ControlVisible = False
状态:ControlChecked = False-ControlVisible = 真(粗体)
状态:ControlChecked = 真(粗体)-ControlVisible = 真(粗体)
状态:ControlChecked = 真(粗体)-ControlVisible = 真(粗体)
状态:ControlChecked = 真(粗体)-ControlVisible = 真(粗体)
ControlChecked似乎按预期方式工作。将ControlVisible设置为false并将粗体反转时,它会继续翻转回True。在我看来,基本形式的[DefaultAttributeValue]为true不能被识别。
更新:
进行了修订,以修复错误并更准确地隔离问题。
更新:
如果我在BaseForm的构造函数中设置checkBox1.Visible = false,那么一切都会按预期进行。因此,最重要的是,麻烦在于要使DefaultValueAttribute为true才能在继承形式的自定义属性中被识别。
最佳答案
您的checkBox1
在基类中是私有(private)的吗?如果不是,那么应该这样做,因为设计人员将序列化两个 setter (一个用于checkBox1.Visible,另一个用于ControlVisible),并且只有序列化的顺序才能确定最终状态,这是不好的。
另外,请查看Form1.designer.cs文件中自动生成的InitializeControls方法,它是否将自定义属性显式设置为默认值?
最后,尝试使用ShouldSerialze and Reset,看看您是否得到了不同的行为。
编辑
我在本地重新创建了问题,并附加了一个VS实例来调试另一个。 VS首次评估属性ControlVisible
时,它返回false
,因为checkBox1.Visible
(获取方法的源代码)是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);
}
}
当继承上面的
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; }
}
关于c# - 以基本形式定义的自定义属性在重建时会以继承形式失去其状态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6872849/