I've got an editable datagrid on a WPF form inside an MVVM application.
There are two possible actions a user can take on this page that cause some data inside one of the rows to change. One of the editable fields - Requested - can cause another property to change, and there's a style trigger dependent on its value:
public bool OverRequested
{
get
{
if(this.Requested > this.Volume)
{
return true;
}
return false;
}
}
And in the XAML:
<DataGridTextColumn Header="Requested" Binding="{Binding Requested}">
<DataGridTextColumn.CellStyle>
<Style TargetType="DataGridCell">
<Style.Triggers>
<DataTrigger Binding="{Binding OverRequested}" Value="true">
<Setter Property="Foreground" Value="Red"/>
<Setter Property="ToolTip" Value="The requested volume is greater than the available volume" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
The other is a button that updates the data item behind the row and changes a value on the item.
Although the datagrid itself is responsive to changes - if you add or remove rows from the underlying ObservableCollection it updates accordingly in the UI - changes to these properties on the items underneath the rows do not update.
I understand that this is by design, in the sense that changes to items inside an observableCollection do not bubble up, and have to be watched for specifically, but I'm struggling to find out how to achieve what I want.
I've tried - as suggested elsewhere - overriding the event handler for CollectionChanged on the ObservableCollection to add a notification alert to the items inside:
private void ObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
(item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
}
}
}
But items inside do not implement the INotifyPropertyChanged interface - they're Entity Framework objects and not ViewModels. So the cast fails.
Is there a way I can implement this? With only two properties to watch, I'd happily do it manually - but even calling OnPropertyChanged("") to update all the properties in the ViewModel doesn't cause those inside the datagrid to refresh.
Maybe you can try it another way, using converters. I have an app that does something like that. I usually need a test app to get this stuff just right, but try this:
The converters would look something like this:
Don't forget to add the converters to your app.xaml: