Что такое хороший способ получить контейнеры элемента ListView? - PullRequest
0 голосов
/ 11 апреля 2019

У меня вопрос к 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.

1 Ответ

1 голос
/ 11 апреля 2019

ItemsControls имеет свойство Item​Container​Generator, которое содержит объект Генератор контейнеров элементов, который можно использовать для получения контейнеров элементов для элементов и индексов элементов и т. П.

* 1006 Е.Г. *

var container = listView.ItemContainerGenerator.ContainerFromItem(item);

В UWP ContainerFromItem и аналогичные методы также напрямую доступны в классе ItemsControl, так что вы можете написать

var container = listView.ContainerFromItem(item);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...