Better way to update bound controls when changing the datasource
It's not a whole lot better, using Binding.ReadValue
might save the hassle of unbinding and rebinding, assuming the object you are binding to remains the same:
foreach (Control c in pnlBody.Controls)
foreach (Binding b in c.DataBindings)
b.ReadValue();
If, on the other hand, you are changing the underlying bound object, this will not work. I suggest putting a BindingSource
between the Binding
s and the Row
object, this way you only have to re-bind the binding source and not all 50 bindings individually. Either by a call to BindingSource.CancelEdit()
or by resetting the data source:
RowBindingSource.DataSource = null;
RowBindingSource.DataSource = this.Row;
Related videos on Youtube
Nevyn
Been doing C# Application Development for around 6 years now. Working mostly with Winforms and .NET. I have also done some basic work with ASP.NET using a C# code base.
Updated on September 15, 2022Comments
-
Nevyn almost 2 years
The problem. I have a databinding to the fields within a property on my form for a large number of textboxes on the form itself. I am changing not just a field value within the property, but the entire property (resetting to a previously saved default).
What I wanted to do was something like this:
((CurrencyManager)BindingContext[Row]).Refresh();
Doesn't work,
BindingContext[Row]
is aPropertyManager
, not aCurrencyManager
, and doesn't have a refresh method.PushData()
is protected and not accessable. I also tried callingthis.Refresh()
, and individually on each control I tried callingc.Refresh
...Now What?Here's the code Im currently using:
private void btnReset_ButtonClicked(object sender, EventArgs e) { Row = ResetRow.Clone();//use clone to break the reference, dont want to be updating the ResetRow when Row fields change. foreach (Control c in pnlBody.Controls) if (c.DataBindings.Count > 0) c.DataBindings.Clear(); DataBindandSet();//re-apply all the databindings (50) } //just a sample of the databinding function itself private void DataBindandSet() { txtAzimuth.DataBindings.Add(new NullableBinding("Text", Row, "Azimuth", true)); txtBHTemp.DataBindings.Add(new NullableBinding("Text", Row, "BHTemp", true)); //repeat 48 more times }
Update I set the databindings to the full databinding string, to see if setting the null value default had any effect, it didnt.
txtAzimuth.DataBindings.Add(new NullableBinding("Text", Row, "Azimuth", true, DataSourceUpdateMode.OnPropertyChanged, ""));
Row
is a public property on the form itself.ResetRow
is a private property on the form, its assigned to a clone of the initial row on Form Load and never changed, it serves as a backup. The value of some of the properties (but not all) is allowed to be null, and should display as an empty string. This is what the NullableBinding class does behind the scenesCan anyone think of a better way to do this than removing and re-applying every single one of the databindings?
-
Nevyn over 11 yearsI have no idea why, because that looks great on paper....but it isn't updating the textbox. Good thought though, and more efficient, if only slightly, than clearing and rebinding everything.
-
lc. over 11 years@Nevyn Just a thought but is the textbox a direct child of
pnlBody
? -
Nevyn over 11 yearsYes, all the bound controls are inside pnlBody. The form itself has also has pnlHeader and some buttons and side panels. That's also why im checking
c.Databindings.Count
, because the textboxes have some labels beside them that I dont really care about. -
lc. over 11 years@Nevyn Re-reading your question I understand you are changing the object
Row
points to? If so I think the binding still keeps the reference to the old object, which is why this doesn't work. I'd try putting aBindingSource
between the bindings and theRow
object. -
Nevyn over 11 yearsstill doesn't seem to work. Tried
BindingSource.CurrencyManager.Refresh()
andBindingSource.ResetBindings()
. Refuses to update the data in the textboxes. -
lc. over 11 years@Nevyn I think you have to re-bind the
BindingSource
if you change the bound object (BindingSource.DataSource = null; BindingSource.DataSource = Row;
). But it's now down to one place instead of 50. -
Nevyn over 11 yearsPretty close. I rethought it slighty. Refresh and Reset didn't work, but BindingSource treats the property like a List Entry...
BindingSource.CancelEdit()
looks like it works just fine. I might not even have to save a copy of the row for that to work...I will accept this as the answer, although I encourage you to edit the answer to what it actually is, rather than what you have up there :-) -
lc. over 11 years@Nevyn Ok, edited. If you have more to add you can either comment or even just put your own answer with what you got to work and accept that instead :)
-
Michael Murphy almost 9 years
ControlBindingSource.DataSource = null;
Did not work for me. -
ProfK over 7 yearsBecause everybody always binds their forms to
DataTables
. Those are history by now, my friend.