Reputation: 1841
I know I'm using sunset technology here, but I'd like to find a solution to my problem nonetheless.
I have an entity with some simple fields. I can bind textboxes on a form like this
nameTextBox.DataBindings.Add(new Binding("Text", entity, "Name"));
I did the same for a date field,
evaluationDatePicker.DataBindings.Add(new Binding("Value", entity, "EvaluationDate"));
and this too works fine as long as the EvaluationDate property is of type DateTime.
However, if I now modify the entity and make EvaluationDate nullable, the binding becomes one-way. That is, the control reflects the property value (as long as it's not null), but it doesn't update the entity when I pick another date in the UI.
In line with the recent Windows Forms policy of not throwing exceptions but rather pretend all is well even when things fail (a major annoyance in my book; Form_Load too now just swallows exceptions, though in this case of course we're way past Form_Load before the error occurs). So in fact I can't even tell if it's trying to do anything, but I have to assume it is, given that the two-way binding is working perfectly fine as long as the property isn't nullable.
How can I overcome this?
What I'm trying to do is write a base class for presenters in the application which has the ability to databind controls based on a simple naming convention. The presenter knows that for TextBox it should bind the Text property, for CheckBox it should bind "Checked", and so on. The mapping between properties and controls is done by convention - controls presenting a field should have the same name as the field plus the control type. Hence "Name" presented in a TextBox maps to "NameTextBox" (which is the convention I like to use anyway - I have never understood why people are still fond of prefixes specifically with GUI controls, but no other kind of code!?) and "IsMarried" in a checkbox would become "IsMarriedCheckBox".
All of this allows the presenter to offer a method that accepts an object, "datasource", and a container where the controls to be bound are living. This makes for very rapid work adding a bunch of fields to a screen compared to having to use a bindingsource and write code, a solution which like mine does not give any compiler checks and does mean it's easy to break things by mistypes and property renames.
But to make my little PoC I want to know what I can handle with this, and what sorts of things will still require other solutions. The whole thing would be considerably more valuable if it could support properties of nullable types, since we use them a lot. (Nor do I want to stop using them; bundling together the concept of "has a value" and if so "which value" is elegant and makes for less code, as well as more compiler help.)
Is there a way? Anything I can hook into? Or possible to make a generic type of my own to replace Nullable<T>? Since I don't understand why it doesn't work without me having to do anything, it's difficult to imagine what might be worth trying to work around it.
Upvotes: 0
Views: 1786
Reputation: 1101
evaluationDatePicker.DataBindings.Add(
new Binding("Value", entity, "Nullable", true, DataSourceUpdateMode.OnValidation));
Last argument can be replaced with DataSourceUpdateMode.OnPropertyChanged as needed
Upvotes: 4