Как правильно изменить размер полосы прокрутки при изменении базовой коллекции WPF ListView?

Как правильно изменить размер полосы прокрутки при изменении базовой коллекции WPF ListView?

У меня есть WPF ListView, привязанный к наблюдаемой коллекции с несколькими тысячами элементов. Когда их большое количество удалено, вид, кажется, показывает только последний элемент. Когда я перемещаю позицию в представлении с помощью ползунка, размер ползунка изменяется в соответствии с новым размером коллекции. Можно ли принудительно синхронизировать ListView и полосу прокрутки при изменении коллекции?


person Thomas Bratt    schedule 06.07.2009    source источник


Ответы (3)


Я нашел обходной путь, если у кого-то еще есть эта проблема.

В следующем примере кода показано изменение источника элементов списка ListView в первой строке. Следующие строки показывают обходной путь - просто вернуться к первому элементу.

this.ListViewResults.ItemsSource = this.itemsFiltered;

object firstItem = this.ListViewResults.Items.GetItemAt(0);

if(firstItem == null)
{
    return;
}

this.ListViewResults.ScrollIntoView(firstItem);
person Thomas Bratt    schedule 06.07.2009
comment
Это прекрасно работает! Задайте источник данных / источник элементов, найдите первую строку и прокрутите до нее! - person Jared Harley; 09.10.2009
comment
Была ли у вас такая же проблема? Я не мог найти много случаев, когда это видели другие люди. - person Thomas Bratt; 13.10.2009

Странное поведение !!

Я бы попытался установить для контекста привязки (Context) ListView значение null, а затем снова тот же список, чтобы обновить привязки.

person Martin Randall    schedule 06.07.2009
comment
Нет, похоже, это не работает. Я попытался установить MyListView.DataContext как null, так и пустой набор данных. - person Jared Harley; 09.10.2009

У меня есть другой обходной путь, который требует создания подкласса ListView. Это немного больше работы, но результат лучше, чем просто прокрутка до первого элемента. Но вам необходимо адаптировать шаблон ListView таким образом, чтобы у ScrollViewer в шаблоне было имя (здесь PART_ScrollViewer), или вы можете использовать другой способ получить объект ScrollViewer.

public class BetterListView : ListView
{
    ScrollViewer sv;
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
       //Get the scrollviewer in the template (I adapted the ListView template such that the ScrollViewer has a name property)
       sv = (this.Template.FindName("PART_ScrollViewer", this)) as ScrollViewer;
    }

    protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
    {
        base.OnItemsChanged(e);
        //Prevent the bug where the ListView doesn't scroll correctly when a lot of items are removed
        if (sv != null && e.Action == NotifyCollectionChangedAction.Remove)
        {
            sv.InvalidateScrollInfo();
        }
    }
}
person J W    schedule 02.09.2009
comment
Привет, я пробовал этот метод, но this.Template.FindName (PART_ScrollViewer, this) возвращает значение null. - person VHanded; 12.01.2011