Reputation: 23
I'm trying out WPF and I have an application with an ObservableCollection
hooked up to a ListView
. It adds the items perfectly and everything is falling together. It is taking in data from a live source and so item values are getting updated and rows are getting added. But now I want the most recent rows to be highlighted, text changed, something to show that this certain row is being changed. So I set up a data trigger and added a value to the DataType
in the ObservableCollection
called RecentlyChanged
. If its true, then set the text to red, otherwise text is black.
When I run this code the list items change to red and then never change back and I have tried everything and it is ticking me off. I've checked the debugger to and even when the value is no
(I'm using strings yes
and no
because i wanted to try all sorts of data types) it stays red. Code for the data trigger is below:
--Edit: Added in the second datatrigger that i tried using before to no avail.
<ListView ItemsSource="{Binding DataTable, UpdateSourceTrigger=PropertyChanged}">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="Foreground" Value="Black"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=RecentlyChanged}" Value="yes">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=RecentlyChanged}" Value="no">
<Setter Property="Foreground" Value="Black" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Resources>
Upvotes: 2
Views: 2227
Reputation: 7437
The issue is that the ObservableCollection
only reports changes to the collection itself, in other words, it fires a CollectionChanged
event whenever items are added or removed, but not when properties of those items change. In order to achieve the desired result - updating a data trigger when an item's property changes - the item itself must implement the INotifyPropertyChanged
interface and fire the PropertyChanged
event when the desired property is set.
In this case, you can use the following:
using System.ComponentModel;
public class ListViewItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
var propChanged = PropertyChanged;
if(propChanged != null)
{
propChanged(this, new PropertyChangedEventArgs(name));
}
}
private string recentlyChanged = "yes"; // Recently changed on creation
public string RecentlyChanged
{
get { return recentlyChanged; }
set {
recentlyChanged = value;
OnPropertyChanged("RecentlyChanged");
}
}
// ... define the rest of the class as usual
}
WPF magic should take care of the rest.
Upvotes: 4