WPF Listview - выбор элементов за пределами «поля зрения» - PullRequest
1 голос
/ 11 мая 2010

Я использую ListView для отображения элементов в списке. Пользователь может выбрать элементы сам или использовать некоторые «ключи предварительного выбора» для выбора элементов с указанными атрибутами.

Для проверки предметов я использую что-то подобное:

for(int i;i<MyListView.Items.Count;++i)
{
    if( /*... Check if the items should be selected ...*/ )
        (MyListView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem).IsSelected = true;
}

Это прекрасно работает для предметов, которые видны во время исключения. Но для элементов, которые не видны, ContainerFromIndex () возвращает ноль. Я слышал, что это как-то связано с виртуализацией, и что Список не знает об элементах «вверх» или «вниз» «поля зрения». Но как получается, что выбранные элементы в Списке могут находиться вне поля зрения, когда вы выбираете их вручную?

А как сделать выбор элемента вне «поля зрения»? Я думаю, что это должно быть возможно.

Спасибо за любую помощь, Marks

Ответы [ 2 ]

2 голосов
/ 11 мая 2010

Как вы упомянули, я предполагаю, что проблема заключается в виртуализации элементов ListView. По умолчанию ListView (и ListBox) используют VirtualizingStackPanel в качестве своей ItemsPanel для повышения производительности. Краткое объяснение того, как это работает, можно прочитать здесь .

Однако вы можете заменить другую панель. В этом случае попробуйте использовать обычный StackPanel. Если у вас есть множество элементов в ListView, особенно если это сложные элементы, производительность может немного снизиться.

<ListView>
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/>
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

Редактировать

Вы также можете попытаться найти решение, описанное по этому же вопросу , в зависимости от вашей модели. Тем не менее, это, вероятно, не будет работать для вас.

0 голосов
/ 26 мая 2016

При работе с элементами управления виртуализацией альтернативой отключению виртуализации (которая иногда бывает полезна, даже если она мешает правильной работе других частей API) является поиск VirtualizingPanel и указание это явно для прокрутки.

Например:

void ScrollToIndex(ListBox listBox, int index)
{
    VirtualizingPanel panel = FindVisualChild<VirtualizingPanel>(listBox);

    panel.BringIndexIntoViewPublic(index);
}

static T FindVisualChild<T>(DependencyObject o) where T : class
{
    T result = o as T;

    if (result != null)
    {
        return result;
    }

    int childCount = VisualTreeHelper.GetChildrenCount(o);

    for (int i = 0; i < childCount; i++)
    {
        result = FindVisualChild<T>(VisualTreeHelper.GetChild(o, i));

        if (result != null)
        {
            return result;
        }
    }

    return null;
}

Я не очень доволен необходимостью поиска по визуальному дереву, чтобы найти панель, но я не знаю ни другого способа получить ее, ни прокрутки до определенного индекса при работе с панелью виртуализации. .

...