Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContext not refreshed when changing object value

I have a grid and its DataContext is assigned from code behind:

CustomerDataGrid.DataContext = _customerobj;

When some functions are executing, the _customerobj object gets changed:

_customerobj = obj;

But DataContext doesn't update according to the new object details. If I use the following it does update:

_customerobj = obj;
CustomerDataGrid.DataContext = _customerobj;

Do I need to follow the same when each time _customerobj is updated or have I missed something?

like image 839
New Developer Avatar asked Jan 14 '23 07:01

New Developer


2 Answers

What you're experiencing is not caused by not implementing INotifyPropertyChanged.

When you do CustomerDataGrid.DataContext = _customerobj;, you're setting the DataContext to a certain value. When afterwards you're setting _customerobj = obj;, you're just giving a _customerobj a new value, but DataContext still references the original object, so it won't change.

For example:

string a = "hello";
string b = a; // b points to "hello"
a = "world";  // a points to "world"
              // but b's pointer doesn't change

Console.WriteLine(b); // Outputs "hello"

This means that you'll have to set the DataContext as well.

Note: This isn't actually the way things work for strings, since .NET strings are immutable, but hopefully this gets the point across.

like image 86
Adi Lester Avatar answered Jan 17 '23 14:01

Adi Lester


@AdiLester 's answer above is correct and is the reason this happens.
That said, if you'd rather set the DataContext only once, and still have the object change in the grid you could wrap your property (in a ViewModel for instance), bind the grid to the property and then when the property will change the grid will also change.

For example:

public class MyViewModel : INotifyPropertyChanged
{
   private MyObj _customerObj;
   public MyObj CustomerObj
   {
       get { return _customerObj;}
       set
        {
            if (_customerObj != value)
            {
                _customerObj = value;

                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("CustomerObj"));
                }
            }
        }
   }
}

Now you can do:

 MyViewModel vm = new MyViewModel();
 vm.CustomerObj = //Whatever;
 CustomerDataGrid.DataContext = vm;

And when you bind your grid use: {Binding CustomerObj}

like image 31
Blachshma Avatar answered Jan 17 '23 14:01

Blachshma