我遇到了基本表单的属性无法在继承的表单中维持状态的麻烦。

环境:

  • Visual Studio 2010旗舰版Service Pack 1:版本10.0.40219.1 SP1
  • .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。这些是放置在表单上时控件的默认设置。

    然后,我创建了以下继承形式:
    using System;
    using System.ComponentModel;
    using System.Windows.Forms;
    
    namespace Test
    {
        public partial class Form1 : BaseForm
        {
            public Form1()
            {
                InitializeComponent();
            }
        }
    }
    

    问题和重现步骤:
  • 在设计器中打开Form1时,属性处于以下状态。

    状态:ControlChecked = False-ControlVisible = (粗体)

    ControlVisible设置为True,如预期的那样,但是它是粗体。 [DefaultValueAttribute]在基本形式中设置为true,因此,我希望此属性不会以粗体显示。
  • 我现在在设计器中将ControlVisible更改为False。粗体关闭。

    状态:ControlChecked = False-ControlVisible = False
  • 我现在重建项目,并重新生成Form1中的代码。 ControlVisible属性以粗体形式恢复为True。

    状态:ControlChecked = False-ControlVisible = (粗体)
  • 我现在将ControlChecked从False更改为True,并且按预期方式将其变为粗体。

    状态:ControlChecked = (粗体)-ControlVisible = (粗体)
  • 我重建了项目,没有任何变化。

    状态:ControlChecked = (粗体)-ControlVisible = (粗体)
  • 我现在将ControlVisible的属性从True更改为False,然后再次重建项目。 ControlVisible以粗体翻转回True。

    状态: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/

    10-11 01:46