Ela*_*lan 5 c# inheritance designer properties winforms
我遇到基本形式的属性无法以继承形式维护状态的问题.
环境:
下面是重现的源代码和步骤:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
在上面,默认属性与[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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题和重现步骤:
当我在设计器中打开Form1时,属性处于以下状态.
状态:ControlChecked = False - ControlVisible = True(粗体)
ControlVisible按预期设置为True,但它是粗体.[DefaultValueAttribute] 在基本表单中设置为true,因此我希望此属性不以粗体显示.
我现在在设计器中将ControlVisible更改为False.大胆的关闭.
状态:ControlChecked = False - ControlVisible = False
我现在重建项目并重新生成Form1中的代码.该ControlVisible属性恢复为真粗体.
状态: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,大胆的反转.在我看来,无法识别基本形式中的[DefaultAttributeValue]为true.
更新: 修改以修复错误,更准确地隔离问题.
更新: 如果我在BaseForm的构造函数中设置checkBox1.Visible = false,那么一切都按预期工作.因此,最重要的是,似乎问题是在继承的表单中的自定义属性上识别为DefaultValueAttribute为true.
你的私人是checkBox1基类吗?如果不是,那就应该是,因为设计器将序列化两个 setter(一个用于 checkBox1.Visible,另一个用于 ControlVisible),并且只有序列化的顺序才能确定最终状态,这是不好的。
另外,查看 Form1.designer.cs 文件中自动生成的 InitializeControls 方法,它是否显式将自定义属性设置为默认值?
最后,尝试使用ShouldSerialze 和 Reset并查看是否会得到不同的行为。
编辑
我在本地重新创建了该问题,并附加了一个 VS 实例来调试另一个实例。VS第一次ControlVisible评估该属性时,它返回,false因为checkBox1.Visible(获取器源)是false. 当创建并显示实际的复选框控件,并且滚动“属性”窗口以显示ControlVisible它的值时,它会再次计算并返回true,这是默认值,但是 VS 内部似乎已经将该属性标记为已修改,因为它是初始值与默认值不同。这可能是VS的一个bug。
我创建了一个简单的效果演示:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
当继承上述内容时,BaseForm其TestPropery行为与您的示例中的完全相同ControlVisible,所以我认为这是 VS 中的一个错误。
问题的解决方案是使用简单的布尔支持字段作为帮助器,因为 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; }
}
Run Code Online (Sandbox Code Playgroud)