WPF ListView confuses SelectedItem with equal elements

ListView (or ListBox) with the following properties:

<ListView SelectionMode="Single"> <sys:String>James</sys:String> <sys:String>Claude</sys:String> <sys:String>Justing</sys:String> <sys:String>James</sys:String> </ListView> 

will lead to the selection of two elements at the same time if I click on "James", although I chose SelectionMode = "Single". This is even the same behavior when I use a helper class with a string property to display in a ListView. It seems that the ListView evaluates the items and selects those that are equal to () rather than ReferenceEqual (). Is there a way to change this behavior so that ListView processes each item separately?

+4
source share
2 answers

Well, I was wrong. The problem is actually Equals() compared to ReferenceEquals() .

This is even the same behavior when I use a helper class with a string property to display in a ListView.

Not really. You get the same behavior if you use an anonymous helper class.

Why doesn't wrapping an anonymous type around the string fix the problem? As described here , when creating an anonymous type, the compiler creates a common Equals() method that returns true if the objects are of the same (anonymous) type and their properties have the same value.

The solution is to implement a real (not anonymous) class - it can be that simple:

 public class Item { public string Display { get; set; } } 

Object.Equals() makes a reference comparison, so until you redefine it, you get the behavior you expect.

+2
source

To get the desired behavior, you need to create a helper class that wraps the string type as follows:

 public class Item { public Item(string name) { Name = name; } public string Name { get; set; } } 

Using it, you can do the following:

 private ObservableCollection<Item> _items; public MainWindow() { InitializeComponent(); _items = new ObservableCollection<Item>() { new Item("James"), new Item("John"), new Item("Steve"), new Item("Drew"), new Item("Andy"), new Item("James") }; list.ItemsSource = _items; } 

with XAML as follows:

 <ListView SelectionMode="Single" x:Name="list" DisplayMemberPath="Name" /> 
0
source

All Articles