Wpf 列表框ScrollIntoView不';不适用于可变高度项目

Wpf 列表框ScrollIntoView不';不适用于可变高度项目,wpf,Wpf,我有一个列表框,其中添加了各种项目。当一个新项目被添加到列表框中时,我需要将该项目滚动到视图中(基本上滚动到底部) 我已经试过了,也试过了 但是,这两种解决方案都不起作用,因为我的列表框包含可变高度的项。如果我将我的列表框项目模板改为固定高度,那么它似乎可以工作。以下是我的一个项目模板的示例: <DataTemplate x:Key="StatusMessageTemplate"> <Grid Grid.Column="1" VerticalAlignment="top

我有一个列表框,其中添加了各种项目。当一个新项目被添加到列表框中时,我需要将该项目滚动到视图中(基本上滚动到底部)

我已经试过了,也试过了

但是,这两种解决方案都不起作用,因为我的列表框包含可变高度的项。如果我将我的列表框项目模板改为固定高度,那么它似乎可以工作。以下是我的一个项目模板的示例:

<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>


如何使新项目滚动到视图中,而不考虑其高度?

我想我已经找到了问题所在。在显示之前,不会计算可变高度项目。因此,我添加了一个计时器来调用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();
System.Windows.Threading.DispatcherTimer dTimer=new System.Windows.Threading.DispatcherTimer();
dTimer.Interval=新的时间跨度(0,0,0,0,200);//200毫秒
dTimer.Tick+=新事件处理程序(
(seder,ea)=>
{
//Verses.ScrollIntoView(Verses.Items[itemIndex]);
for(int i=0;i
我需要将该项目滚动到视图中(基本上滚动到底部)

当列表框中的项目高度可变时,ScrollIntoView的行为会很奇怪

如果唯一的目的是滚动到底部,您可以直接访问Scrollviewer并滚动到最大可能偏移量,如下所示

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;
}
var scrollViewer=getgenderantbytype(ListBoxChats,typeof(scrollViewer))作为scrollViewer;
scrollViewer.ScrollToVerticalOffset(Double.MaxValue);
公共静态可视GetDegenantByType(可视元素,类型)
{
if(元素==null)
{
返回null;
}
if(element.GetType()==type)
{
返回元素;
}
Visual foundElement=null;
if(元素为FrameworkElement)
{
(元素作为FrameworkElement);
}
for(int i=0;i

GetDegenantByType是punker76@

在调用ScrollIntoView()时编写的一个帮助函数,是否确实引用了ListBox项的顶级Framework元素,而不是ListBoxItem的一个子控件?我不确定这是否会有不同,但如果有,它可能正是按照你的要求做的。我试过的这两个类都使用listitem,所以我很确定这不是问题所在。