ApplicationSettings bindings: TextBox vs ToolStripTextBox behaviour

cjard

Well-known member
Joined
Apr 25, 2006
Messages
7,081
Programming Experience
10+
I've noticed something slightly puzzling.

I have a menu on my form with a textbox embedded on the menu (ToolStripTextBox) and i have another TextBox on the main form panel. Both have a .Text property that are bound to SomeSetting - a setting string in the user settings. The binding is correct and the text of the setting shows in both boxes when starting the app. Annoyingly, when I edit the TextBox.Text, the SettingChanged event fires, but when I edit the ToolStripTextBox.Text, the settings changed event does not fire and indeed, the new contents of the TSTextBox are not written into the settings area.

Can anyone explain the quirky behaviour? For now I think I will attach an event handler to the TSTextBox.TextChanged event and set the setting myself, but it shouldnt be necessary?
 
The reason for the difference is that the regular TextBox is a control and the ToolStripTextBox is not. The Control class has a DataBindings property and it is a Binding object added to that collection that handles the two-way traffic between the TextBox and the application setting. Because the ToolStripTextBox is not a control it has no DataBindings collection so it has no two-way communication with the application setting.
 
OK, I did a little more investigation on this. A ToolStripTextBox is not a control, as I said. It is a component that acts a host for a control, specifically a ToolStripTextBox.ToolStripTextBoxControl, which is derived from TextBox. That means that you can get a reference to the hosted control via the ToolStripTextBox's Control property and cast it as TextBox. Once you have that reference you can bind to the application setting manually. I added a ToolStripTextBox and a regular TextBox to the same form and linked both their Text properties to the same application setting. I then went to the designer code and copied the line that added the binding to the regular TextBox. I then pasted that line into the form's Load event handler and changed the reference from the regular TextBox to the ToolStripTextBox's Control property. Since you're accessing the DataBindings property, which is inherited from Control, there's not even a need to cast. Voila! Editing the contents of either field updated the other.
VB.NET:
Me.ToolStripTextBox1.Control.DataBindings.Add(New System.Windows.Forms.Binding("Text", _
                                                                               Global.WindowsApplication1.My.MySettings.Default, _
                                                                               "TextBoxText", _
                                                                               True, _
                                                                               System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged))
 
Last edited:
Excellent! Thanks for putting the time in to that! Would you suggest, then, that even though the Visual IDE allows me to bind the ToolStripTextBox (being the only accessible visible component part of this particular problem) .Text to the application settings, that there is a bug in the code generated by the IDE to perform the binding?

Or that the ToolStrip family of controls are not exposed in the right way? i.e. the IDE incorrectly makes them appear manipulable, but it is directing its attention to the wrong thing (i.e. the host container rather than the control itself) ?
 
You could look at it either of two ways. You can bind properties of other components to application settings, like the ConnectionString of a DbConnection object, but there is no two-way communication possible there either. Components are not controls and only controls offer that two-way communication. The ToolStripTextBox is not a control so it is reasonable that that's how it behaves. Having said that, it looks and feels like a control, mainly because it does host a control, and it will be used like a control, so it is reasonable to expect it to behave like a control with respect to data-binding. Bascially you have two choices if you want that two-way binding behaviour. You can either do what I did in that previous post, or else you can inherit ToolStripTextBox and add the functionality yourself.
 
Back
Top