2013-04-14 2 views
1

Я реализовал панель виртуализации, которая работает очень хорошо, панель реализует IScrollInfo. Я нахожусь в процессе работы с помощью клавиатуры. Панель используется в ListView как ListView.ItemsPanel. Когда пользователь нажимает вниз, выбранный элемент правильно изменяется, но прокрутка не происходит, и когда вы достигаете последнего видимого элемента, вы больше не можете нажимать. Я пытаюсь понять, как узнать панель о выбранном элементе и прокрутить ее соответствующим образом. Я пробовал искать, но я не могу найти что-либо, связанное с тем, что я хочу сделать. Было бы полезно оценить точку в правильном направлении.WPF VirtualizationWrapPanel Выбранный элемент Изменение причины прокрутки

Edit: Here является код VirtualizingWrapPanel

+0

Можем ли мы увидеть код для вашей 'Custom Panel'? –

+0

@RohitVats Я добавил ссылку на источник Panel. – OriginalMoose

+0

У меня такая же проблема сейчас. Любые новости об этом? – ygoe

ответ

0

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

В методе ArrangeOverride при переходе по дочерним элементам я делаю следующее.

var listViewItem = child as ListViewItem; 
if (listViewItem != null) 
{ 
    listViewItem.Selected -= ListViewItemSelected; 
    listViewItem.Selected += ListViewItemSelected; 
} 

В MeasureOverride я сделать вызов CleanUpItems здесь нам нужно будет отказаться от выбранного события.

var listViewItem = children[i] as ListViewItem; 
if (listViewItem != null) 
{ 
    listViewItem.Selected -= ListViewItemSelected; 
} 

Я также добавил следующие три функции.

private void ListViewItemSelected(object sender, RoutedEventArgs e) 
{ 
    var listViewItem = sender as ListViewItem; 
    if(listViewItem == null) return; 

    var content = listViewItem.Content as CollectionViewGroup; 
    if(content != null) return; //item is a group header dont click 

    var items = ItemContainerGenerator as ItemContainerGenerator; 
    if(items == null) return; 
    BringIndexIntoView(items.IndexFromContainer(listViewItem)); 
    listViewItem.Focus(); 
} 

protected override void BringIndexIntoView(int index) 
{ 
    var offset = GetOffsetForFirstVisibleIndex(index); 
    SetVerticalOffset(offset.Height); 
} 

private Size GetOffsetForFirstVisibleIndex(int index) 
{ 
    int childrenPerRow = CalculateChildrenPerRow(_extent); 
    var actualYOffset = ((index/childrenPerRow) * ChildDimension.Height) - ((ViewportHeight - ChildDimension.Height)/2); 
    if (actualYOffset < 0) 
    { 
     actualYOffset = 0; 
    } 
    Size offset = new Size(_offset.X, actualYOffset); 
    return offset; 
} 

Функция GetOffsetForFirstVisibleIndex, вероятно, варьируются в зависимости от реализации, но это должно быть достаточно информации, если кто-то еще возникают проблемы придумывают решения.

+0

Когда я пытаюсь это сделать, выбранный элемент всегда находится точно в середине представления. Выбор не перемещается вверх или вниз до границы и прокручивается только тогда, но он всегда прокручивается. Кроме того, Up/PageUp и Down/PageDown всегда перемещают выделение по одной строке. Таким образом, это не похоже на хорошее или полное решение исходной проблемы. – ygoe

+0

@LonelyPixel То, как он прокручивается, - это то, как я решил реализовать его. Я хотел кое-что немного по-другому, вы можете заставить его работать, как хотите, изменив GetOffsetForFirstVisibleIndex. Метод просто возвращает смещение, которое будет просматриваться в представлении. Что касается страниц PageUp и PageDown, я не могу использовать эти элементы управления (мои пользователи используют удаленный доступ, поэтому ключи ограничены), поэтому я ничего не сделал с их реализацией. Я просто разместил этот код, чтобы другие могли видеть, как подключить панель для получения уведомления об изменении выбранного элемента. – OriginalMoose

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