Рассмотрим простой пример:Почему ComboBox потеряет свой SelectedItem при сортировке ItemsSource?
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);
}
}
}
При запуске программы, a
выбран. При нажатии Sort
выбор не изменяется, но список сортируется (по-прежнему, как и ожидалось).
Если вы а) еще раз нажмите Sort
или б) выбрать b
или c
до сортировки, то ComboBox
теряет свой выбор и SelectedItem
становится null
.
Я определил проблему до метода ObservableCollection.Move
. Похоже, что когда вы вызываете Move(i, i)
(так что вы ничего не двигаете), i
является SelectedItem
, выбор идет в ад.
Я не ищу решение. Очевидным обходным решением было бы не сортировать ObservableCollection
и использовать CollectionViewSource
или настроить метод Sort
только для звонка Move
, когда два индекса фактически отличаются.
Вопрос, который у меня есть, почему это происходит в первую очередь? В документации для метода Move
нет указаний на то, что вы не должны передавать один и тот же параметр дважды. Также нет намека на то, почему это не будет работать в документации для CollectionChanged
event или CollectionChangedEventArgs
class. Это ошибка в WPF?