2009-10-23 3 views
7

ItemsControlのデータはObservableCollectionにバインドされています。新しいモデルをリストに追加するコードの中に、このメソッドがあります。私は新しい項目(リストの一番下にある)をビューにスクロールしたいと思います。ItemsControl内の新しい項目をスクロールして表示

ItemsControlのサイズは、モデルの追加前後でActualHeightが同じであるため、サイズを照会しているときにまだ更新されていないと思います。このコードの効果は、新しい項目の少し上の点までスクロールすることです。

新しいActualHeightはどのようになるのでしょうか?ここで

が私のコードです:私はあなたがアイテムコンテナに BringIntoViewを呼び出すために必要だと思う

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

答えて

5

、ないのItemsControl自体:

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

編集:実際にはこれはしていませんこの時点ではアイテムコンテナはまだ生成されていないため、イベントは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はまだContainersGeneratedへのステータス変更後にnullを返しますが、と私は考えている理由:S


編集:これは仮想化のためです:コンテナは表示する必要があるときにのみ生成されるため、隠しアイテム用にコンテナは生成されません。 ItemsControl(VirtualizingStackPanel.IsVirtualizing="False")の仮想化をオフにすると、上記の解決方法は問題ありません。

+0

DocumentElements.ItemContainerGenerator.ContainerFromItem(model)はnullを返しますか?ビューがまだデータソース内の新しい項目に更新されていないと思います。 –

+0

ああ、はい、私はそれを忘れていました...しかし、もしItemsControlにまだコンテナがないなら、スクロールすることはできません:S –

+0

私の更新された回答を参照してください –

関連する問題