Я пытаюсь реализовать ListView с GridView с сортируемыми столбцами.
Чтобы отсортировать ListView, я подключаю событие Click для GridViewColumnHeaders и добавляю SortDescriptors в источник представления по умолчанию (аналогично тому, что сделано в MSDN ).
Примерно так:
<ListView ItemsSource="MY ITEMS SOURCE BINDING">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="MY DISPLAYMEMBER BINDING">
<GridViewColumnHeader Content="My Header" Click="ColumnHeaderClicked"/>
Все это прекрасно работает, но я бы хотел немного обобщить. Для этого я просто извлек GridViewColumnHeader и написал обработчик кликов. Я знаю, что существует множество реализаций сортируемых списков, которые обычно происходят из ListView, но мне просто интересно, возможен ли такой подход.
Примерно так:
<ListView ItemsSource="MY ITEMS SOURCE BINDING">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn DisplayMemberBinding="MY DISPLAYMEMBER BINDING">
<local:SortableGridViewColumnHeader Content="My Header"/>
Чтобы это работало, мне нужно перейти от кода SortableGridViewColumnHeader к содержащему ListView, чтобы установить новые SortDescriptors.
Я пытался перемещаться вверх по родительской лестнице, но GridViewColumnHeader не является визуальным потомком моего ListView. Конечно, я мог бы создать свойство зависимости и связать его с ListView, но вместо этого должен быть способ перехода к нему.
Как бы я сделал это в коде? (Я не ищу ответы о том, как сортировать списки WPF в общем, мне интересно, можно ли это сделать таким образом).
EDIT
Оказалось, что мне нужен был родительский искатель в обработчике кликов моего производного GridViewColumnHeader.
DependencyObject parent = this;
do
{
parent = VisualTreeHelper.GetParent(parent);
if (parent == null) return;
} while (!(parent is ListView));
Теперь моя сортировка работает как брелок.