0
votes

I have a problem with data bound properties of a textbox mapped to a custom class, for the most part it works without problems; when i update a value in the bound object the changes appear in the textbox Text property, if i set the objects property to null then it gets properly formatted to "-No Data-", but when i set the object as null the Text value in the textbox remains without changes.

I have 2 classes

Class1
Class2

Class1 implements INotifyPropertyChanged in the following way:

public class Class1: INotifyPropertyChanged
{
   private string _serial;

   public event PropertyChangedEventHandler PropertyChanged;
   protected void OnPropertyChanged(string propertyName = null)
   {
       if (PropertyChanged != null)
       {
          PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
       }
   }

   [DisplayName("Serial Number")]
   public string SerialNumber
   {
     get { return _serial; }
     set
     {
       _serial = value;
       OnPropertyChanged("SerialNumber");
     }
   }
 }

Class2 inherits from Class1:

public class Class2: Class1
{
  //My props & methods, etc.
}

In my form i bind the textbox Text property in the following way:

Class2 myobject = new Class2();

myobject.SerialNumber = "1234";

//I only need the textbox to display, not update the datasource
//so i use DataSourceUpdateMode.Never
mytextbox.DataBindings.Add("Text", myobject, "SerialNumber",true,DataSourceUpdateMode.Never,"-No Data-");

Later on if i do the following assignments in the object this is what happens:

myobject.SerialNumber = "123"; //mytextbox Text is "123"
myobject.SerialNumber = "456"; //mytextbox Text changes to "456"

myobject.SerialNumber = "123"; //mytextbox Text is "123"
myobject.SerialNumber = null;  //mytextbox Text changes to "-No Data-"

myobject.SerialNumber = "123"; //mytextbox Text is "123"
myobject = null;               //mytextbox Text remains "123" <-this is the problem

Shouldn't the textbox Text change to "-No Data-" since the whole object is null?

Am i missing something to properly display the desired data?

4

4 Answers

1
votes

Setting myobject to null merely drops the reference to that object for that variable name. The actual instantiated object is still bound in the DataBindings, so in order to change the value of that object, you would then need to access it from there via textbox.DataBindings["SerialNumber"].

If you set the SerialNumber to null, that's a different matter, of course. It may then display "-No Data-" for you as a default value for null.

If you wish to remove the binding to that object, then you'll need to call the Remove method on your DataBindings collection e.g.

private void RemoveSerialNumberBinding()
{
   Binding serialNumberBinding = textBox1.DataBindings["SerialNumber"];
   textBox1.DataBindings.Remove(serialNumberBinding);
}

https://msdn.microsoft.com/en-us/library/system.windows.forms.controlbindingscollection.remove%28v=vs.110%29.aspx

1
votes

Passing myobject as data source to DataBindings.Add implies that the object will not change, only the properties.

If you indeed need to bind later different object or set it to null, rather than writing special functions to do that, you need to use an intermediate data source that allows changing the "current" object. The easiest way is to use a single item list inside either BindingSource or BindingList<T>.

Here is an example with BindingSource:

Form members:

BindingSource dataSource = new BindingSource { DataSource = typeof(Class2) };
Class2 selectedObject;
Class2 SelectedObject
{
    get { return selectedObject; }
    set
    {
        selectedObject = value;
        dataSource.Clear();
        dataSource.Add(value);
    }
}

Bindings (one time initialization in constructor/load event):

mytextbox.DataBindings.Add("Text", dataSource, "SerialNumber", true, DataSourceUpdateMode.Never, "-No Data-");
// similar for other controls

Data operations:

SelectedObject = new Class2 { SerialNumber = "1234" }; //mytextbox Text is "1234"
SelectedObject.SerialNumber = "123"; //mytextbox Text is "123"
SelectedObject.SerialNumber = "456"; //mytextbox Text is "456"
SelectedObject.SerialNumber = null;  //mytextbox Text is "-No Data-"
SelectdObject.SerialNumber = "123";  //mytextbox Text is "123"
SelectedObject = null;               //mytextbox Text is "-No Data-"
SelectedObject = new Class2 { SerialNumber = "2345" }; //mytextbox Text is "2345"
0
votes

The line "myobject = null" doesn't destroy the object, the object still exists. You just don't have a reference to it. You should clear databindings of your textbox.

In normal case you should have some ViewModel class (that implement INotifyPropertyChanged) with "myobject" property, this ViewModel class should be bound to the DataContext of the View, and "myobject" property should be bound to the textbox. After you clear "myobject" property then value in UI disappears.

0
votes

when you set myobject = null, then your app is trying to get the SerialNumber property of null. How can it compare and tell that is different if it cannot get the property? I imagine it would work if you never let your object be null.

instead of

myobject = null; 

do this

myobject = new Class2();