8

我有一个ItemsControl数据绑定到ObservableCollection. 我在后面的代码中有这个方法,它向列表中添加了一个新模型。然后我想将新项目(在列表底部)滚动到视图中。

我认为ItemsControl当我查询尺寸时,尺寸尚未更新,因为ActualHeight添加模型之前和之后是相同的。这段代码的效果是滚动到略高于新项目的位置。

我怎么知道新ActualHeight的会是什么?

这是我的代码:

        ViewModel.CreateNewChapter();
        var height = DocumentElements.ActualHeight;
        var width = DocumentElements.ActualWidth;
        DocumentElements.BringIntoView(new Rect(0, height - 1, width, 1));
4

1 回答 1

6

我认为您需要调用BringIntoView项目容器,而不是 ItemsControl 本身:

var container = DocumentElements.ItemContainerGenerator.ContainerFromItem(model) as FrameworkElement;
if (container != null)
    container.BringIntoView();

编辑:实际上这不起作用,因为此时项目容器尚未生成......您可能可以StatusChanged处理ItemContainerGenerator. 我尝试了以下代码:

public static class ItemsControlExtensions
{
    public static void BringItemIntoView(this ItemsControl itemsControl, object item)
    {
        var generator = itemsControl.ItemContainerGenerator;

        if (!TryBringContainerIntoView(generator, item))
        {
            EventHandler handler = null;
            handler = (sender, e) =>
            {
                switch (generator.Status)
                {
                    case GeneratorStatus.ContainersGenerated:
                        TryBringContainerIntoView(generator, item);
                        break;
                    case GeneratorStatus.Error:
                        generator.StatusChanged -= handler;
                        break;
                    case GeneratorStatus.GeneratingContainers:
                        return;
                    case GeneratorStatus.NotStarted:
                        return;
                    default:
                        break;
                }
            };

            generator.StatusChanged += handler;
        }
    }

    private static bool TryBringContainerIntoView(ItemContainerGenerator generator, object item)
    {
        var container = generator.ContainerFromItem(item) as FrameworkElement;
        if (container != null)
        {
            container.BringIntoView();
            return true;
        }
        return false;
    }
}

但是它也不起作用......由于某种原因,ContainerFromItem在状态更改为 后仍然返回 null ContainersGenerated,我不知道为什么:S


编辑:好的,我现在明白了......这是因为虚拟化:容器仅在需要显示时生成,因此不会为隐藏项目生成容器。如果您为 ItemsControl ( ) 关闭虚拟化VirtualizingStackPanel.IsVirtualizing="False",则上述解决方案可以正常工作。

于 2009-10-23T20:07:44.910 回答