2009-10-23 63 views
7

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

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

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

这里是我的代码:

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

回答

5

我认为你需要调用BringIntoView物品容器上,而不是ItemsControl的本身:

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

编辑:其实这不工作,因为在这一点上,物品容器尚未产生...您可能可以处理ItemContainerGeneratorStatusChanged事件。我尝试下面的代码:

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仍返回状态更改为ContainersGenerated后空了,我不知道为什么:S


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

+0

DocumentElements.ItemContainerGenerator.ContainerFromItem(model)returns null?我认为View并未更新到数据源中的新项目。 – 2009-10-23 20:33:55

+0

啊,是的,我忘记了......但无论如何,如果容器不在ItemsControl中,你不能滚动到它:S – 2009-10-23 23:15:38

+0

看到我更新的答案 – 2009-10-24 00:31:01