Data Binding fails me again...

Please excuse this minor tirade I'm about to belch out...

I've never been a fan of automatic data binding.  I still remember the full page ads in Visual Basic Programmers Journal showing sample screenshots of an Access employee databased hooked in to a  VB3 for with very little coding.  It looked sweet and demo'd well, but in practice, the data binding was never good enough for production work.  As I recall, VB4/5/6 didn't show any big improvements in data binding.

.NET 1.x showed noticeable improvements in data binding.  To be honest, I never used data binding in 1.x, but heard it was much more robust -- yet still lacked in some areas and was, at times, cumbersome to use.

Now that .NET 2.0 is here, I've got a chance to look at data binding again.  I've read a lot of nice things about the improvements in data binding with 2.0 and was cautiously optimistic that it may be something I could actually put to good use.  I whipped up a quick sample app and was impressed at how easy it was to bind control properties to datasource properties.  But before doing this in my production app, I had one more aspect to get right.

I want to control exactly when the controls are loaded with property values from the datasource and I wanted to control exactly when the datasource was updated from the controls.  The reason?  I've got a configuration form that I want to display some values to the user.  They can edit and change stuff using the UI, but I don't want the datasource updated unless they press the "OK" button.  If they press "Cancel", I just close the form.  If the press "OK", I was going to tell all the Binding objects to Write their values to the datasource.

From reading the documentation, I thought I could get this kind of control by setting the DataSourceUpdateMode to Never (never update the datasource unless I explicitly call WriteValue on the Binding object) and setting ControlUpdateMode to Never (never update the control unless I explicitly call ReadValue on the Binding object).  So I set out to implement this (what I thought!) very easy sample:

 

b = new Binding("Text", _config, "Desc", false, DataSourceUpdateMode.Never);
b.ControlUpdateMode = ControlUpdateMode.Never;
textBox1.DataBindings.Add(b);

 

My datasource (_config) has a "Desc" property I'm binding to the "Text" property of textBox1.  As you can see both DataSourceUpdateMode and ControlUpdateMode are set to Never.  The code shown above is inside my Form ctor, right after InitializeComponent.  Yet what happens when my ctor exits?

THE PROPERTY SETTER ON 'Desc' IS CALLED AND IT'S SET TO AN EMPTY STRING!!

Sorry for shouting.  But The call is coming from "external code" (according to the Debug Location dropdown) -- in other words, not my code.  As a matter of fact, those three lines are about the only code added to the Form -- there is no other code in my sample app that sets the Desc property.  Why is the setter being called?  I've set DataSourceUpdateMode to Never.  I can't see any reason why the "Desc" property should be touched.

Argh...  Bit in the a$$ again by data binding.

9 Comments

  • In 1.1 on the Cancel we simply RejectChanges on the DataSource. Is this not an option for you?

  • No. The datasource is just a class with a bunch of properties I'd like to bind to controls so I don't have to write all the code to move the values back and forth.

    Thanks though.

  • Tried your code, but haven't experienced the same behaviour, property is written only when I invoke Binding.WriteValue().

  • What you want to do is create a BindingSource that you can then tell it when to flush the changes into the data source.  

    The bindingsource object is the go between the UI and the Data Object (business entity or datarow) in .Net 2.0.  It works flawlessly with datasets and data rows or business objects as well. I have a config form similar to yourself and it works like this.

    If they press "OK", this gets run:

    myBindingSource.EndEdit();

    object.Save(); // sudo code for sample only

    This essentially flushes the changes to the wired datasource (can be whatever you want).

    If they hit the cancel button this get called:

    myBindingSource.CancelEdit();

    Nothing gets written to the object.  As long as your data source implements IEditableObject interface you should be good to go.


  • I'm working exactly with the same code but I have 2 textboxes in a Form.
    and when we press OK:

    Textbox1.DataBindings("Text").WriteValue()
    Textbox2.DataBindings("Text").WriteValue()

    WriteValue just works for Textbox1!!

    Any Idea?

  • Data binding in .NET 2.0 is pretty same as all others ever done by microsoft - useless. Completely malfunctioning, unsafe, insecure, bogus, unpredictable, and most of the time you would end up writing more retarded c# code than oracle scripts.

    As to the problem above this comment, it is a common malfunction of databinding. Simply, if you attempt to control the writing/reading behavior of Binding class, it will --REVERT-- changes of all other non-bound fields/properties. Therefore, only first bound control gets updated due to the fact it is the only one which has access to CHANGED data, after its done with the update, it reverts the changes back thus canceling them, so other bindings are useless.

    Now the original problem which is the cause of Patrick's post - also a common problem. You will end up having erased, blanked-up data, reverted data, scrambled data all the time. So, if you like your data getting completely annihilated, data binding is the way to go.
    Patrick, the manual control-update algorithm is simply not working, it's an internal problem and should not even be considered an option, it's simply a dummy feature. You will notice that unlike DataSourceUpdateMode, ControlUpdateMode can only be called from a single property, only in Binding class. No constructor parameter, no defaulting, no nothing, just a dummy property spawned by microsoft gremlins.
    There is also a horde of bugs mentioned in MSDN relating to binding. E.g. it can't work with combo boxes, check list boxes, list views (mostly), dt pickers, etc.

    Best regards,
    Bojan Sala

  • It's such a relief to find I'm not the only one banging his head on this particular wall!!
    I'm using bindingsources, and having a number of problems binding to objects, mostly caused by the fact that the data is passed thru' the binding on validation, plus canceling validation does not cancel the binding etc etc.
    Keith - IEditableObject has to be implemented in your own code within the object. But the data - even bad data, that fails validation, is passed thru via the property setter first, where it either throws an exception or even worse, a silent first chance exeption - which means a user could think they've corrected a typo but the data hasn't changed!

    So I wrote some code to iterate thru' the bindings in the bindingsource and set them to 'never' in both directions, and then 'read' and 'write' procedures to take a bindingsource an iteratively read/write the data.
    Great, I thought, taken control of exactly when and if to bind, plus it's now entirely separate from the validation code.

    Does it work?

    No.

    As Patrick says, the readvalue method is broken. All the controls remain empty. If anybody CAN get this to work I'd love to know - I really thought this time we have databinding that works, plus we have those neat error icons yo can hook-up to the bindingsource etc etc But no. MS STILL can't get it right.

  • DataBinding in .NET 2.0 is just broken. I've never seen a DataBinding system that actually worked correctly, lease of all this one. WriteValue and EndEdit calls basically do nothing (no data is ever saved to the backend data store). Taking control over when data is committed to the database is just a joke. Data binding is one of those features you have to use Microsoft's way and their way only. If you don't, it will simply fail to work or will require you to jump through hoops. Just getting a simple form with Edit/View mode and the ability for the user to decide when to save data is a pain.

  • I have exactly the same problem. Did anyone make any further progress on this?

Comments have been disabled for this content.