Florian
Florian

Reputation: 1887

Datagrid not updating after data change

I have a WPF DataGrid bound to a ObservableCollection via dg.ItemsSource = myCollection;

The MyClass implements INotifyPropertyChanged. I have a calculated property which is calculated async.

The property is a SolidColorBrush bound to the color of the Text. After the value of the property changes the DataGrid does not update immediately, but it updates as soons as I select the line of the item of which the property changed it display the updated value.

What can I do to let the DataGrid update immediately? I can't use XAML binding for the ItemsSource.

Binding:

<DataGridTextColumn Foreground={Binding Path=MyBrushProperty} />

Code of the class:

public class MyClass : INotifyPropertyChanged
{
public SolidColorBrush MyBrushProperty {
   get {
      CalcMyBrush();
      return _myBrushProperty;
   }
  set{
   _myBrushProperty = value; 
   OnPropertyChanged("MyBrushProperty");
  }
}
private void CalcMyBrush(){
   //DoSomething that changes _myBrushProperty and takes some time and needs to run async and after that sets
   MyBrushProperty = somevalue;

}
}

Upvotes: 0

Views: 3001

Answers (2)

MichaelLo
MichaelLo

Reputation: 1319

Notice you cannot change UI items from different threads (read about STA Apartment State). The idea is that the creating thread is the single owner of the created item. For example, the following code is no good for two reasons: 1. The NotifyOfPropertyChange("MyBrushProperty"); might be called before the task is calculatd. 2. And less obvious, the task content will result in an exception saying:

The calling thread cannot access this object because a different thread owns it. There might be a few problems here.

Make sure you turn on all exception flags or explore the color property in _myBrushProperty

    public class ModuleBMainWindowViewModel : Screen , INotifyPropertyChanged
{
    public ModuleBMainWindowViewModel()
    {
        _myBrushProperty = new SolidColorBrush(Colors.White);
        DisplayName = "ModuleB";
        CalcMyBrush();

    }
    private SolidColorBrush _myBrushProperty;
    public SolidColorBrush MyBrushProperty
    {
        get
        {
            return _myBrushProperty;
        }
        set
        {
            _myBrushProperty = value;
        }
    }
    private void CalcMyBrush()
    {
         Task.Run(() =>
        {
            //DoSomething that changes _myBrushProperty and takes some time and needs to run async and after that sets
            _myBrushProperty = new SolidColorBrush(Colors.Blue);
        });

         NotifyOfPropertyChange("MyBrushProperty");
    }
}

Upvotes: 0

potehin143
potehin143

Reputation: 531

I think you need to rise PropertyChanged event for your calculated property after you got async result of calculation.

something like this

public SolidColorBrush MyBrushProperty{get{return myBrushProperty;}}
private void CalcMyBrush()
{
    var awaiter = YourAsyncCalculation.GetAwaiter();
    awaiter.OnComplited(()=>
    {
     myBrushProperty= (SolidColorBrush)awaiter.GetResult();
     OnPropertyChanged("MyBrushProperty"); 
    });
}

Upvotes: 1

Related Questions