WPF VirtualizingWrapPanel选定的项目更改导致滚动

时间:2013-04-14 18:07:51

标签: wpf scroll virtualization selectionchanged

我已经实现了一个非常好的虚拟化面板,该面板实现了IScrollInfo。我正在使用键盘让它工作。 Panel在ListView中用作ListView.ItemsPanel。当用户正确按下所选项目但更改但没有滚动时,当您到达最后一个可见项目时,您无法再按下。我试图弄清楚如何使面板知道所选项目并适当滚动。我试过四处寻找,但我似乎找不到任何与我想做的事情有关的事情。我们将非常感谢正确方向上的一点。

编辑:Here是VirtualizingWrapPanel的代码

1 个答案:

答案 0 :(得分: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函数可能会根据您的实现而有所不同,但如果其他人在提出解决方案时遇到问题,这应该是足够的信息。