Reputation: 1887
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
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
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