У меня вопрос к UWP, но решение может быть таким же в WPF, поэтому я тоже отметил это.
Я пытаюсь реализовать этот метод расширения в пользовательском GridView иListView, чтобы при изменении выделения выбранный элемент всегда плавно анимировался в представлении.
Метод расширения отлично работает.Однако получение контейнера UIElement для его отправки не так хорошо работает.
ListView.Items привязан к коллекции в ViewModel.Итак, ListView.Items - это не UIElements, а объекты данных.Мне нужен соответствующий контейнер UIElement для SelectedItem.
Сначала я попробовал это:
void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_scrollViewer != null && this.ItemsPanelRoot != null && this.Items.Count > 0)
{
var selectedListViewItem = this.ItemsPanelRoot.Children[this.SelectedIndex];
if (selectedListViewItem != null)
{
_scrollViewer.ScrollToElement(selectedListViewItem);
}
}
}
Сначала это работает, но на самом деле ничего хорошего.Индексы ListView.ItemsPanelRoot.Children в конечном итоге начинают расходиться с ListView.Items, поскольку макет обновляется динамически.
Затем я попытался это сделать, что до сих пор работает нормально:
void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_scrollViewer != null && this.Items.Count > 0)
{
var selectedListViewItem = this.ItemsPanelRoot.FindDescendants<ListViewItem>()
.Where(x => x.Content == this.SelectedItem).FirstOrDefault();
if (selectedListViewItem != null)
{
_scrollViewer.ScrollToElement(selectedListViewItem);
}
else
{
throw new Exception();
}
}
}
Проблема в том, что выполнение такого запроса каждый раз кажется невероятно дорогим, а также небезопасным, поскольку еще нет уверенности в том, что контейнер доступен.Я чувствую (надеюсь), что мне чего-то не хватает, и что есть правильный способ сделать это.
Примечание: «FindDescendants» - это метод расширения из Windows UI Toolkit, выполняющий те же действия, что и VisualTreeHelper.