I recently came upon what seems to be an oddity of win forms property binding in that if a control starts out life* as invisible, the control doesn't seem to see changes in the bound property. In this case I was binding a label's .Visible
property to Properties.Settings.Default.BooleanSetting
(default False) in the application settings. I was also binding a checkbox .Checked
to the same setting, the idea being that toggling the checkbox to checked would cause the label to appear and unchecked would cause it to disappear. All setup was done in the forms designer
This only worked reliably when the setting was True at application startup. If the setting was False, the checkbox would be unchecked, and the label invisible but checking the checkbox would not show the label. Upon debugging it turned out that the value of the setting was true, so the checkbox had updated it, but the label's Visible
property was still false
Other bound properties didn't seem to have a problem if the label was initially visible; Enabled
could be bound and would reliably flip state when the checkbox was toggled regardless of the initial value of the setting. The problem seemed to be specifically if the label started out invisible - an invisible label with its Enabled
property bound to that boolean wouldn't change Enabled state.
The workaround seemed to be to store Properties.Settings.Default.BooleanSetting
, set it to true before calling InitializeComponent()
then revert it. In this case the form would show, and checking the box would reveal the invisible label
var b = Properties.Settings.Default.FormatWithoutConfirmation;
Properties.Settings.Default.FormatWithoutConfirmation = true;
InitializeComponent();
Properties.Settings.Default.FormatWithoutConfirmation = b;
I first drew the conclusion (with some help from a related question here - asking about how to make it work) that a control needs to be initially visible for binding to work, and having a control invisible puts the control in the catch 22 of never being Visible in order to see the change in Visible..
It does seem to be a one time setup thing rather than a "if a control ever goes invisible it stops listening" thing because if it always affected an invisible control then a control that started out visible would go invisible and never return - this isn't the case, and initially visible controls toggle visibility on and off perfectly.
One sticking point for me in the initially-visible theory is that, according to the code in the windows designer, binding happens before the visibility is set:
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;
At the time binding is set up here, Visibility must be True because that's the default for the Visible
property. It seems like there is something else that happens later to finish off the setup, or that there is a critical moment early in a control's life (but not this early) where something happens to it that determines whether it will or won't listen to bound property changes
I get the feeling that the answer might be out there somewhere in MSDN as one of the answers in that question I linked to said...
assume that binding to a control's Visible property is broken, despite the fact that it sometimes works. See http://support.microsoft.com/kb/327305, which says as much
...but the link given to MSDN has rotted. Another related question I read mentioned that initially invisible controls don't have handles when created and mooted it as a possible factor
*not sure when a control's life starts, ref the "visibility is set after binding is created" note