将ItemsControl中的新项目滚动到视图中

时间:2009-10-23 19:55:46

标签: wpf data-binding datatemplate itemscontrol

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

我认为在查询大小时ItemsControl的大小尚未更新,因为添加模型前后的ActualHeight是相同的。此代码的效果是滚动到略高于新项目的点。

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

这是我的代码:

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

1 个答案:

答案 0 :(得分:5)

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

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

编辑:实际上这不起作用,因为此时尚未生成项容器...您可以处理StatusChanged的{​​{1}}事件。我尝试了以下代码:

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,我不明白为什么:S


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