2017-02-15 2 views
1

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

В целом, это может быть выполнено путем звонка ListViewItem.BringIntoView или ListView.ScrollIntoView(ListViewItem).

Однако ListView привязан к элементу ListCollectionView, а Source - это ObservableCollection элементов ViewModel. Итак, я добавляю элементы ViewModel в эту коллекцию. Затем элемент View создается через привязку.

Поскольку элемент находится за пределами видимой области, ListViewItem не создается сразу, а тем более реализуется. Если представление прокрутки близко к нижней части ListView, ListViewItem будет создан и реализован вскоре после этого.
Если прокрутка находится где-то посередине ListView, это не сработает.

Установка IsVirtualizing на значение false будет исправлять проблему, потому что элемент затем создается и реализуется в любом случае. Но это, очевидно, имеет некоторые недостатки производительности.

Итак, я пытаюсь найти способ, чтобы элемент, только что добавленный в коллекцию, был создан и реализован и, в конечном счете, может быть представлен в поле зрения.

Есть ли у кого-нибудь идеи, как подойти к этой проблеме?


Если вид прокрутки закрыт на дно, он в основном работает, но имеет странное поведение, когда оказывается, что только каждый ListViewItem приводится в поле зрения.

+0

Как вы добавляете новые товары? Каковы их типы? Я имею в виду, они строки? – Ron

ответ

1

У VirtualizationPanel есть метод BringIndexIntoViewPublic, который генерирует элемент и делает его видимым.

Вот пример со всем соответствующим кодом.

public class ListView_ViewModel 
{ 
    private CollectionViewSource _collectionViewSource; 
    private ObservableCollection<ListViewItem_ViewModel> _listViewItemViewModels; 
    private ListView _listView; 

    private void AddItem() 
    { 
    var newListViewItemViewModel = new ListViewItem_ViewModel(); 
    _listViewItemViewModels.Add(newListViewItemViewModel); 
    var indexOfNewItem = _collectionViewSource.View.Cast<ListViewItem_ViewModel>() 
          .ToList().IndexOf(newListViewItemViewModel); 
    var virtualizingPanel = VisualTreeHelper.FindChild<VirtualizingPanel>(_listView); 
    virtualizingPanel.BringIndexIntoViewPublic(indexOfNewItem); 
    } 
} 
0

Трудно сказать точную проблему, основанную на вашем вопросе. Однако это может быть из-за поведения функции Equals. Рассмотрим эту структуру:

<DockPanel> 
    <Button Name="addItem" Click="addItem_Click" Content="Add new and scroll" DockPanel.Dock="Bottom"/> 
    <ListView Name="sv" ScrollViewer.VerticalScrollBarVisibility="Visible"> 
    </ListView> 
</DockPanel> 

Существует кнопка, которая пытается добавить новые предметы и прокрутить до конца.

Это будет работать, если вы добавляете элементы, которые не то же самое:

private void addItem_Click(object sender, RoutedEventArgs e) 
{ 
    if (sv.ItemsSource == null) 
     sv.ItemsSource = new ObservableCollection<string>(); 

    string newitem = "new item" + (sv.Items.Count + 1).ToString(); 
    ((ObservableCollection<string>)sv.ItemsSource).Add(newitem); 
    sv.ScrollIntoView(newitem); 
} 

Обратите внимание, что строки никогда не равны (см (sv.Items.Count + 1).ToString() часть). Тем не менее, это не будет работать:

private void addItem_Click(object sender, RoutedEventArgs e) 
{ 
    if (sv.ItemsSource == null) 
     sv.ItemsSource = new ObservableCollection<string>(); 

    string newitem = "new item"; 
    ((ObservableCollection<string>)sv.ItemsSource).Add(newitem); 
    sv.ScrollIntoView(newitem); 
} 

с момента Equals возвращает первый элемент.

+0

Это интересно. Я скопировал ваш код и смог проверить, что я вижу такое же поведение. Однако в моем случае я добавляю «новый ListViewItem», и это, похоже, имеет значение. Я только что установил тестовую программу, в которой я добавляю «новый ListViewItem()» в цикле for. С "item.BringIntoView "не работает. С" ListView.ScrollIntoView (item) "он отлично работает в моей тестовой программе. Это, безусловно, отличается от того, что я вижу в реальной программе. Но я не думал, что это сделает любая разница. – Em1

+0

Я проверяю код с помощью '' ListViewItem'' и работает. Вы должны отправить свой код для дальнейшей справки. – Ron

+0

Я мог бы исправить это, установив «VirtualizingPanel.IsVirtualizing =« False ». Я не думал об этом Прежде всего, мне придется вникать в это дальше. Я не совсем понял, что здесь происходит. Спасибо всем. – Em1

Смежные вопросы