Comments are closed for this post.
Posted by
Rodney Richardson
@
15 May 2006
4:01 AM
Very neat. You're not, however, unhooking the event handler when setting Nullable to false. If you set it to true, then later set it to false it will still be hooked up, and still be parsing the field.
Posted by
Bruusi
@
15 May 2006
10:46 PM
Hi Rodney,
I am glad that you enjoyed the post and understand your reasoning, but you have to remember that the code is actually generated at design time, and is included in the InitializeComponent() function in the designer generated file.
That means that the "Property" is only set once and the 'SetNullableBinding' method only called once when the Form or UserControl is initialised. I have included the example code below.
// Code generated in designer.
// SetNullableBinding only called once
this.nullableExtender1.SetNullableBinding(this.nullableIntTextBox, true);
// Other code generated by designer.
this.nullableIntTextBox.Size = new System.Drawing.Size(100, 20);
...
You could of course call the 'SetNullableBinding' function on the extender control twice yourself and then experience the problem you describe, but this would not be a very likely scenario.
Posted by
Li
@
18 May 2006
12:07 PM
If you assign a null value to a textbox, does it stay that way after a postback if no changes are made?
Ex (in Page_Load):
if(!this.IsPostback)
{
mytextbox.Text = null;
}
else if(mytextbox.Text == null)
{
mylabel.Text = “stayed null”;
}
else
{
mylabel.Text = “changed to something else”;
}
Posted by
Josh Einstein
@
09 Jun 2006
1:03 PM
I agree with Rodney. You can't make assumptions about the caller. The example should be amended to properly unhook it.
Good example otherwise though.
Posted by
Jim
@
22 Jun 2006
5:59 PM
When set the "NullableBinding on nullableExtender1" property to 'true' I get the following:
"Property value is not valid."
Details are:
Object reference not set to an instance of an object.
if I add the line:
this.nullableExtender1.SetNullableBinding(this.txtColorId, true);
to the designer file I get the following error in the designer.
NullableExtender.SetNullableBinding(Control control, Boolean nullable) in C:\WIP\VSS\VS2005\QSStudioMaster.root\QSStudioMaster\QSStudio\FrameworkUI\ FilterableList\NullableExtender.cs:line 55
The code Builds but when it runs I get "Object reference not set to an instance of an object" on line 55.
line 55 is:
control.DataBindings["Text"].Parse += new ConvertEventHandler(NullableExtender_Parse);
The value at this break is:
control.DataBindings["Text"] is 'null'
Am I missing other some other needed code to create these objects? Or is this possibly becuase I am because I am binding a usercontrol at runtime that contains the detail view of the item that seleceted in a datgridview?
Thanx for any help you may have.
Posted by
Jim
@
22 Jun 2006
6:19 PM
I guess I didn't go far enough before the last post:
If I bind at design time to my business object this works fine. Is it possible for me to do this at runtime
using the utility method:
public static void BindField(Control control, string
propertyName, object dataSource, string dataMember)
{
Binding bd;
for (int index = control.DataBindings.Count - 1;
index >= 0; index--)
{
bd = control.DataBindings[index];
if (bd.PropertyName == propertyName)
control.DataBindings.Remove(bd);
}
control.DataBindings.Add(propertyName, DataSource,
DataMember);
}
Maybe I need to rearchitect how I am doing the Master-Detail view. Right now each time a row is changed I am rebinding the detail(usercontrol) to the selected row in the datagridview.
Posted by
Bruusi
@
23 Jun 2006
6:07 AM
Hi Jim,
the bug you encountered is of course something I overlooked in the example code. The code should of course check to see if there is a binding available on the "Text" property of the textbox and not add the Parse event if there isn't.
Thanks for you comments and be sure to let me know how you get on!
Posted by
Kris
@
02 Oct 2006
11:55 AM
Did anyone actually get this to work? I'm trying with a property of type int?, and the setter never get's called. It wasn't called before using the extender, and it isn't called now.
What am I doing wrong?
Posted by
Kris
@
02 Oct 2006
12:44 PM
Ok, I found the solution (to previous post). Turns out that the formattingEnabled parameter in the binding needs to be true for data binding to work with Nullable<T> types.
The extender presented here then indeed allows setting null by erasing the field. I had to fix a few bugs though, so here's my code:
[ProvideProperty("NullableBinding", typeof(TextBox))]
class NullableExtender : Component, IExtenderProvider
{
public bool CanExtend(object extendee)
{
return extendee is TextBox;
}
private List<Control> nullables = new List<Control>();
[DefaultValue(false), Category("Data")]
public bool GetNullableBinding(Control control)
{
return nullables.Contains(control);
}
public void SetNullableBinding(Control control, bool nullable)
{
if (nullable)
{
if (!nullables.Contains(control))
{
nullables.Add(control);
control.DataBindings.CollectionChanged += new CollectionChangeEventHandler(DataBindings_CollectionChanged);
Binding binding = control.DataBindings["Text"];
if (binding != null)
{
binding.FormattingEnabled = true;
binding.Parse += new ConvertEventHandler(NullableExtender_Parse);
}
}
}
else
{
if (nullables.Contains(control))
{
nullables.Remove(control);
control.DataBindings.CollectionChanged -= new CollectionChangeEventHandler(DataBindings_CollectionChanged);
Binding binding = control.DataBindings["Text"];
if (binding != null)
{
binding.Parse -= new ConvertEventHandler(NullableExtender_Parse);
}
}
}
}
void DataBindings_CollectionChanged(object sender, CollectionChangeEventArgs e)
{
Binding binding = (sender as ControlBindingsCollection)["Text"];
if (binding != null)
{
binding.FormattingEnabled = true;
binding.Parse -= new ConvertEventHandler(NullableExtender_Parse);
binding.Parse += new ConvertEventHandler(NullableExtender_Parse);
}
}
private void NullableExtender_Parse(object sender, ConvertEventArgs e)
{
string value = e.Value as string;
if (value != null)
{
if (value.Length == 0)
{
e.Value = null;
}
}
}
}
Posted by
Bruusi
@
04 Oct 2006
11:20 AM
Hi Kris,
I have not encountered your problem. Glad you found a solution to it, and thanks a lot for posting it.
B
Posted by
Tudor Vlad
@
26 Nov 2007
3:13 AM
Although not clearly documented, .NET has support for data-binding to Nullable types.
When binding a datasource to a textbox, you can specify a parameter whose value will be interpreted as null.
In our case, we want String.Empty as null; So all we have to do is modify in the Designer.cs file the textbox databindings, setting the nullValue parameter like this:
this.txtBox.DataBindings.Add(new System.Windows.Forms.Binding("EditValue", this.bindingSource, "Property", true, System.Windows.Forms.DataSourceUpdateMode.OnValidation, String.Empty));
PS: in my case the Designer would modify "String.Empty" to some resource. The workaround was to put "" instead of String.Empty
Posted by
John Walker
@
30 Nov 2007
11:27 PM
Tudor,
Thanks for the tip. I'm using it, although I hate going into the designer file and changing anything. I've been burned one too many times doing that, but it beats the alternative of having to do this in code.
The real question here is, why isn't this possible within the Advanced Databindings property grid for the control? I can add other values, but not an empty string. This seems so fundamental to me, it's just infuriating that it's not supported there.
Oh yeah...I'm using VS 2008, so it's still not there.
Posted by
Blake
@
07 Dec 2007
11:46 AM
All of this is great for binding to the 'Text' property on controls because 'Text' always returns an empty string when there is no data in the control; it doesn't return a null reference. The 'SelectedValue' property on the ComboBox is another story, however. If you bind a Nullable type to the SelectedValue of a ComboBox, and then clear the contents of the ComboBox via the user interface, the associated Binding's Parse event is never raised! I believe (but don't know for sure) that the Parse event is not raised because the ComboBox's SelectedValue returns a null reference. Because the Parse event is never raised, we never get the opportunity convert a DBNull value to a null reference.
Anyone have any ideas on this? I've considered trapping the ComboBox's Validating event, and then manually updating the DataSource via ComboBox.DataBindings("SelectedValue").WriteValue(), but there's no guarantee that other Validating event-handlers have had their chances to validate the SelectedValue. In other words, I could be forcing an update to the DataSource before that update is validated.
Posted by
Blake
@
07 Dec 2007
11:56 AM
Addendum to my post above:
I suppose I could manually perform the ComboBox.DataBindings("SelectedValue").WriteValue() in a Validated event-handler (instead of a Validating event-handler) to ensure that the value is validated before updating the data source. But even then, there's no guarantee that my event-handler will fire before any others, which means that other event-handlers can't count on the data source being updated yet.
Posted by
david
@
09 Jan 2008
6:52 AM
It works for me simply adding :
txtField.DataBindings(0).NullValue = ""
where databindings(0) is the binding of text to a Bindingsource and a field of type Date.
Posted by
Markus
@
07 Feb 2008
5:59 AM
Nice article, and very nice comment from david, thank you! Just remove all the Parse stuff from the code listing, and simply assign String.Empty to the NullValue of the binding. Much cleaner, and no reason to unhook an event anymore.
Posted by
John Powell
@
22 Mar 2008
2:23 PM
You can achieve the same effect without code by configuring the following properties on the Binding:
FormattingEnabled = true
NullValue = string.Empty
For example:
textBox1.DataBindings.Add("Text", myClass, "MyTextProperty", true, DataSourceUpdateMode.OnPropertyChanged, string.Empty);
Posted by
Kramer
@
22 Jul 2008
9:03 AM
Has anyone figured out how to bind a nullable to a datagrid column?
Posted by
Grette
@
08 Mar 2009
2:42 PM
Hi all. He who labors diligently need never despair; for all things are accomplished by diligence and labor.
I am from Herzegovina and now teach English, give true I wrote the following sentence: "An overview on how to write a winning resume, including do and don for a successful first impression."
Thank :( Grette.
Posted by
mallikn
@
05 Nov 2010
8:19 PM
just in case some one run into this issue with vs2010 not displaying the nullablebinding/extender property in properties window. go through this.
http://social.msdn.microsoft.com/Forums/en/winformsdesigner/thread/25423e00-b85b-4be1-a86b-0b01abbb4619change the signatures in nullablextender.cs to:
[DefaultValue(false),
Category("Data")]
public bool GetNullableBinding(TextBox control)//(Control control)
{
..}
public void SetNullableBinding(TextBox control, bool nullable)//(Control control, bool nullable)
{
..}