我有ItemsControl
数据绑定到ObservableCollection
。我在后面的代码中有这个方法,它在列表中添加了一个新模型。然后我想将新项目(在列表底部)滚动到视图中。
我认为在查询大小时ItemsControl
的大小尚未更新,因为添加模型前后的ActualHeight
是相同的。此代码的效果是滚动到略高于新项目的点。
我怎么知道新的ActualHeight
会是什么?
这是我的代码:
ViewModel.CreateNewChapter();
var height = DocumentElements.ActualHeight;
var width = DocumentElements.ActualWidth;
DocumentElements.BringIntoView(new Rect(0, height - 1, width, 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
ContainersGenerated
)关闭虚拟化,则上述解决方案可以正常工作。