【发布时间】:2020-04-22 06:28:33
【问题描述】:
我最近发现了一个似乎是 win 表单属性绑定的奇怪之处,如果一个控件在生命* 开始时是不可见的,那么该控件似乎不会看到绑定属性的变化。在这种情况下,我将标签的.Visible 属性绑定到应用程序设置中的Properties.Settings.Default.BooleanSetting(默认为False)。我还将一个复选框.Checked 绑定到相同的设置,其想法是切换复选框以选中会导致标签出现,而取消选中会导致标签消失。所有设置都在表单设计器中完成
这只有在应用程序启动时设置为 True 时才能可靠地工作。如果设置为 False,复选框将被取消选中,标签不可见但选中复选框不会显示标签。调试后发现设置的值是true,所以checkbox更新了,但是label的Visible属性还是false
其他绑定属性似乎没有问题如果标签最初可见; Enabled 可以绑定并且在复选框被切换时可靠地翻转状态,而不管设置的初始值如何。问题似乎特别是如果标签开始不可见 - 一个不可见的标签,其Enabled 属性绑定到该布尔值不会更改启用状态。
解决方法似乎是存储Properties.Settings.Default.BooleanSetting,在调用InitializeComponent() 之前将其设置为true,然后恢复它。在这种情况下,表单将显示,选中该框将显示不可见的标签
var b = Properties.Settings.Default.FormatWithoutConfirmation;
Properties.Settings.Default.FormatWithoutConfirmation = true;
InitializeComponent();
Properties.Settings.Default.FormatWithoutConfirmation = b;
我首先得出结论(在相关问题 here 的一些帮助下 - 询问如何使其工作),控件需要最初可见才能绑定工作,并且控件不可见会将控件放入为了看到可见的变化,永远不可见的捕获 22..
这似乎是一次性设置的事情,而不是“如果一个控件变得不可见,它就会停止侦听”的事情,因为如果它总是影响一个不可见的控件,那么一个开始可见的控件将变得不可见并且永远不会返回 -情况并非如此,最初可见的控件可以完美地打开和关闭可见性。
对我来说,最初可见理论的一个症结在于,根据 windows 设计器中的代码,绑定发生在 可见性设置之前:
this.label4.AutoSize = true;
this.label4.DataBindings.Add(new System.Windows.Forms.Binding("Enabled", global::Namespace.Properties.Settings.Default, "BooleanSetting", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
this.label4.Enabled = global::Namespace.Properties.Settings.Default.BooleanSetting;
this.label4.Location = new System.Drawing.Point(100, 100);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(35, 13);
this.label4.TabIndex = 11;
this.label4.Text = "label4";
this.label4.Visible = false;
在此处设置绑定时,可见性必须为 True,因为这是 Visible 属性的默认值。似乎稍后会发生其他事情以完成设置,或者在控件生命的早期(但不是这么早)有一个关键时刻发生在它身上的事情决定了它是否会听绑定属性更改
我觉得答案可能在 MSDN 的某个地方,作为我链接到的那个问题的答案之一说...
假设绑定到控件的 Visible 属性已损坏,尽管它有时会起作用。见http://support.microsoft.com/kb/327305,上面说了很多
...但是提供给 MSDN 的链接已失效。我读到的另一个相关问题提到,最初不可见的控件在创建时没有句柄,并将其作为可能的因素提出讨论
*不确定控件的生命何时开始,请参阅“创建绑定后设置可见性”注释
【问题讨论】:
-
很有可能,除非控件具有实时
Handle绑定,否则将无法正常工作。 -
如果控件可见性的初始状态是
false,则不会创建句柄。这会对属性绑定产生影响。你可以在这里看到它:CreateControl()。那里的注释已经解释过了。另请注意,该方法将其重载称为CreateControl(false),其中false表示不要忽略可见状态。在那里您可以找到一条注释:只有在控件可见时才“创建”控件。如果您覆盖自定义控件的OnHandleCreated,您会看到它从未被调用过。
标签: winforms data-binding