2013-08-02 41 views
1

我有一個列表框,添加了各種項目。當一個新項目被添加到列表框中時,我需要將該項目滾動到視圖中(基本上滾動到底部)。ListBox ScrollIntoView不適用於可變高度的項目

我從How can I have a ListBox auto-scroll when a new item is added?嘗試瞭解決方案,也從this blog post

然而,無論是解決方案的工作,因爲我的列表框包含可變高度的項目。如果我把我的列表框項目模板改爲固定高度,那麼它似乎工作。以下是我的一個項目模板的示例:

<DataTemplate x:Key="StatusMessageTemplate"> 
    <Grid Grid.Column="1" VerticalAlignment="top" Margin="0,5,10,0"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*"/> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="20"></RowDefinition> 
     </Grid.RowDefinitions> 
     <TextBlock Text="{Binding Path=MessageText}" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" FontWeight="Bold" Foreground="{DynamicResource LightTextColorBrush}"/> 
     <TextBlock Text="{Binding Path=created_at, StringFormat=t}" Style="{StaticResource Timestamp}" TextWrapping="Wrap" HorizontalAlignment="Right" Grid.Row="0" Grid.Column="1"/> 
    </Grid> 
</DataTemplate> 

如何讓新項目滾動到視圖中而不管其高度如何?

+0

當你調用ScrollIntoView(),你確定你有你的列表框項目的頂級FrameworkElement的一個參考,而的不是一個一個輔助函數ListBoxItem的子控件?我不確定這是否會有所作爲,但如果確實如此,它可能會完全符合你的要求。 – Steve

+0

這兩個班我嘗試使用listitem,所以我很確定這不是問題。 –

回答

1

我想我已經找到了問題。直到顯示後纔會計算可變高度項目。所以我添加一個定時器來調用ScrollIntoView函數。但即使這樣也行不通,所以我使用VisualTreeHelper來查找ScrollViewer對象並將其強制到特定行。這是代碼。

 System.Windows.Threading.DispatcherTimer dTimer = new System.Windows.Threading.DispatcherTimer(); 
    dTimer.Interval = new TimeSpan(0, 0, 0, 0, 200); // 200 Milliseconds 
    dTimer.Tick += new EventHandler(
     (seder, ea) => 
     { 
      //Verses.ScrollIntoView(Verses.Items[itemIndex]); 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Verses); i++) 
      { 
       DependencyObject depObj = VisualTreeHelper.GetChild(Verses, i); 
       if (depObj is ScrollViewer) 
       { 
       ScrollViewer sv = depObj as ScrollViewer; 
       sv.ScrollToVerticalOffset(itemIndex); // Zero based index 
       break; 
       } 
      } 
      dTimer.Stop(); 
     }); 
    dTimer.Start(); 
2

我需要滾動該項目到視圖(基本上滾動到底部)。

ScrollIntoView表現奇怪,當列表框具有可變高度的項目。

如果唯一目的是滾動到底部,則可以直接訪問滾動查看器並滾動到最大可能偏移量,如下所示。

var scrollViewer = GetDescendantByType(ListBoxChats, typeof(ScrollViewer)) as ScrollViewer; 
scrollViewer.ScrollToVerticalOffset(Double.MaxValue); 

public static Visual GetDescendantByType(Visual element, Type type) 
{ 
    if (element == null) 
    { 
     return null; 
    } 
    if (element.GetType() == type) 
    { 
     return element; 
    } 
    Visual foundElement = null; 
    if (element is FrameworkElement) 
    { 
     (element as FrameworkElement).ApplyTemplate(); 
    } 
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++) 
    { 
     Visual visual = VisualTreeHelper.GetChild(element, i) as Visual; 
     foundElement = GetDescendantByType(visual, type); 
     if (foundElement != null) 
     { 
      break; 
     } 
    } 
    return foundElement; 
} 

GetDescendantByType是punker76寫@another SO post