I have a ListView
bounded to a List of a class I created. When doing an operating, it was supposed to add/remove items from the list, but my ListView
wasn't updated even though I used INotifyPropertyChanged
.
If I use ObservableCollection
, it works but I need to have the list sorted, and ObservableCollection
doesn't do sorting for WPF4.0 :(
Any way I can make the List binding work? Why didn't it work even though I used INotifyPropertyChanged
?
XAML:
<ListView BorderThickness="0" ItemsSource="{Binding SelectedValues, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Padding="5">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn DisplayMemberBinding="{Binding Value}"></GridViewColumn>
VM:
private List<CheckBoxItem> _selectedValues = new List<CheckBoxItem>();
public List<CheckBoxItem> SelectedValues
{
get { return _selectedValues; }
set
{
_selectedValues = value;
OnPropertyChanged();
}
}
private void UnselectValueCommandExecute(CheckBoxItem value)
{
value.IsSelected = false;
SelectedValues.Remove(value);
//OnPropertyChanged("SelectedValues");
OnPropertyChanged("IsAllFilteredValuesSelected");
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
The CheckBoxItem
class contains 2 properties, Value
and IsChecked
, which I don't think is relevant here.
So basically, I have a button which uses the UnselectValueCommandExecute
to remove items from the list, and I should see the list updated in the UI, but I'm not.
When I debug, I can see the SelectedValues
list updated, but not my UI.
You need a CollectionViewSource
in your UI.
The XAML:
<Window x:Class="WavTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<CollectionViewSource Source="{Binding TestSource}" x:Key="cvs">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Order"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Window.Resources>
<ListView ItemsSource="{Binding Source={StaticResource cvs}}" DisplayMemberPath="Description"/>
</Window>
The code behind:
namespace WavTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var vm = new ViewModel();
this.DataContext = vm;
vm.TestSource.Add(new TestItem { Description="Zero", Order=0 });
}
}
public class ViewModel
{
public ObservableCollection<TestItem> TestSource { get; set; }
public ViewModel()
{
TestSource = new ObservableCollection<TestItem>();
TestSource.Add(new TestItem { Description = "Second", Order = 2 });
TestSource.Add(new TestItem { Description = "Third", Order = 3 });
TestSource.Add(new TestItem { Description = "First", Order = 1 });
}
}
public class TestItem
{
public int Order { get; set; }
public string Description { get; set; }
}
}
Explanation:
The ObservableCollection
raises the PropertyChanged
event as you expect, but you cannot sort it.
So, you need the CollectionView
to sort it and bind the sorted collection to you ListView
/ListBox
.
As you can see, adding an element after the DataContext
initialization affects the UI sorting the last added item ("Zero") correctly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With