Consider this simple example:
MainWindow.xaml
<Window x:Class="WPF_Sandbox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
x:Name="ThisControl">
<StackPanel>
<ComboBox ItemsSource="{Binding Collection, ElementName=ThisControl}" SelectedItem="a" />
<Button x:Name="SortButton">Sort</Button>
</StackPanel>
</Window>
MainWindow.xaml.cs
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace WPF_Sandbox
{
public partial class MainWindow
{
public ObservableCollection<string> Collection { get; } = new ObservableCollection<string>(new [] { "b", "a", "c" });
public MainWindow()
{
InitializeComponent();
SortButton.Click += (s, e) => Sort(Collection);
}
public static void Sort<T>(ObservableCollection<T> collection)
{
var sortableList = new List<T>(collection);
sortableList.Sort();
for (var i = 0; i < sortableList.Count; i++)
collection.Move(collection.IndexOf(sortableList[i]), i);
}
}
}
When starting the program, a
is selected. On pressing Sort
the selection doesn't change but the list gets sorted (still as expected).
If you a) press Sort
again or b) select b
or c
before sorting, the ComboBox
loses its selection and SelectedItem
becomes null
.
I pinpointed the issue down to the ObservableCollection.Move
method. It appears that whenever you call Move(i, i)
(so you do not actually move anything) with i
being the SelectedItem
, the selection goes to hell.
I'm not looking for a solution. Obvious workaround would be to not sort the ObservableCollection
at all and use a CollectionViewSource
or adjusting the Sort
method to only call Move
when the two indices actually differ.
The question I have is, why is this happening in the first place? There is no indication in documentation for the Move
method that you must not pass the same parameter twice. Also there is no hint why this would not work in the documentation for the CollectionChanged
event or the CollectionChangedEventArgs
class. Is this a bug in WPF?