C# 为什么';t ListView.ScrollIntoView是否有效?

C# 为什么';t ListView.ScrollIntoView是否有效?,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我试图滚动到视图中,以便垂直列表视图中的最后一项始终显示,但ListView.ScrollIntoView()永远无法工作 我试过: button1_Click(object sender, EventArgs e) { activities.Add(new Activities() { Time = DateTime.Now, Message = message

我试图滚动到视图中,以便垂直列表视图中的最后一项始终显示,但ListView.ScrollIntoView()永远无法工作

我试过:

button1_Click(object sender, EventArgs e)
{

            activities.Add(new Activities()
            {
                Time = DateTime.Now,
                Message = message
            });

            ActivityList.ItemsSource = activities;

            // Go to bottom of ListView.
            ActivityList.SelectedIndex = ActivityList.Items.Count;
            ActivityList.ScrollIntoView(ActivityList.SelectedIndex);
}
我也尝试过:

ActivityList.ScrollIntoView(ActivityList.Items.Count)
,和
ActivityList.ScrollIntoView(ActivityList.Items.Count+1)但什么都不起作用


请帮忙。这真让人讨厌。以及本例中的文档。

当方法需要item对象时,您正在传入索引。尝试此操作以滚动到所选项目

ActivityList.ScrollIntoView(ActivityList.SelectedItem);
如果要滚动到最后一项,可以使用此选项

ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count - 1]);

您正在分配项的索引,列表框需要该项本身。 试着这样做:

 var activity = new Activities()
        {
            Time = DateTime.Now,
            Message = message
        };

 activities.Add(activity);

 ActivityList.ItemsSource = activities;
 ActivityList.ScrollIntoView(activity);

这与内部列表表示有关,即,当您调用
ScrollIntoView()时,项目还没有就位。
经过多次尝试,我终于想到了这一点,这似乎奏效了:将两个处理程序附加到每个
列表框/ListView:

<ListBox x:Name="YourList" ... Loaded="YourList_Loaded" SelectionChanged="YourList_SelectionChanged">

第二个处理程序你不能没有。设置所选项目后,不能立即调用
ScrollIntoView()
,因为它尚未准备就绪。您必须允许列表在实际更改项目时通知您。第一个处理程序取决于具体情况,如果您在初始加载列表内容后出现选择问题,您可能也需要它。ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count-1])的问题 类似的“解决方案”,至少从我的经验来看,是当列表框多次包含同一项时,它会跳转到它找到的第一个,即最低索引。因此,它不关心您输入的项目的索引,它只是查找该项目并选择第一个

我还没有找到解决方案,但我现在采取的方法是插入而不是添加项。在最初的海报案例中,我认为这将导致:

activities.Insert(0, new Activities()
        {
            Time = DateTime.Now,
            Message = message
        });
或者可能:

ActivityList.Items.Insert(0, new Activities()
        {
            Time = DateTime.Now,
            Message = message
        });

这将导致每个新条目都插入顶部,因此甚至不需要调用ScrollIntoView。

这是一篇旧文章,但由于这里的答案都不适用于我的案例,因此我想添加我的实现。 我在这里找到了解决方案:[

((INotifyCollectionChanged)lvLogs.Items).CollectionChanged+=ListView\u CollectionChanged;
私有无效列表视图\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
ScrollToEnd(this.lvLogs);
}
私有无效列表视图\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs e)
{
if((e.Action==NotifyCollectionChangedAction.Add)&(e.NewItems!=null))
{
尝试
{
ScrollToEnd(this.lvLogs);
}
捕获(例外情况除外)
{
Show(例如ToString(),“错误更新列表视图”,MessageBoxButton.OK,MessageBoxImage.Error);
}
}
}
public void ScrollToEnd(ListView\u ListView)
{
ScrollViewer _ScrollViewer=GetGenderantByType(_ListView,typeof(ScrollViewer))作为ScrollViewer;
_ScrollViewer.ScrollToEnd();
}
公共可视GetDegenantByType(可视元素,类型)
{
if(element==null)返回null;
if(element.GetType()==type)返回元素;
Visual foundElement=null;
if(元素为FrameworkElement)
{
(元素作为FrameworkElement);
}
for(int i=0;i

对我来说,它工作得非常完美。

我面临的问题与此类似。我通过编程向列表框中添加,需要添加最后一项才能显示出来。在使用各种方法后,我发现以下方法是最简单和最好的

lstbox.Items.MoveCurrentToLast();
lstbox.ScrollIntoView(lstbox.Items.CurrentItem);

这是一篇旧文章,但我在Windows应用商店应用程序中遇到了相同的问题,并发现以下问题有效:

    private void PagesListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        pageListView.UpdateLayout();
        pageListView.ScrollIntoView(pageListView.SelectedItem);
    }
干杯,
Paul

只需调用方法UpdateLayout

UpdateLayout();
ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count - 1]);
这会有用的


或者更简单的方法…只需编译app:),它将在没有UpdateLayot()的情况下工作。

我不确定这个主题是否仍然感兴趣,但我无法在我的列表框中使用上述选项。 我在某个地方读到,不相等的项目大小也停止了滚动工作。 我确实使用了下面的Powershell代码;“UpdateLayout()”似乎非常重要:

$zItemsCount = $ListBox.Items.Count - 1
Write-Host -ForegroundColor Cyan "ListBox Items Count - 1:" $zItemsCount
(0..$zItemsCount) | ForEach-Object {
  $ListBox.SelectedIndex = $_
  $ListBox.UpdateLayout()
  $ListBox.ScrollIntoView($ListBox.SelectedItem)
  }#-EndOf: each item -----

根据2013年6月5日14时37分键盘p所述:

如果仍然不起作用,请尝试在ScrollIntoView方法之前调用ActivityList.UpdateLayout()

在我最初认为相同的数据网格之间,我遇到了一个类似的问题。第一个数据网格会滚动到视图中,没有任何问题,第二个数据网格无论如何都拒绝这样做,除非我触发了UpdateLayout。结果证明,我还对第二个数据网格进行了分组:

        mycollection.GroupDescriptions.Clear();
        mycollection.GroupDescriptions.Add(new PropertyGroupDescription("PART"));
        datagrid_parts.ItemsSource = mycollection.View;

显然,如果您的DataGrid正在分组,ScrollViewer将无法获得正确的“可视”空间,因为一些可见区域作为GroupItem保留在组内。参考:

发生这种情况的另一个原因是ItemsPanel已将该项虚拟化,默认情况下,ItemsPanel是一个VirtualzingStackPanel。如果您不需要虚拟化,因为您只有相对较少的项,则可以使用将普通StackPanel替换为您的ItemsPanel

<ListBox>
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Vertical" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
</ListBox>


很抱歉,我忘了提到这是我尝试的第一件事(根据文档)。这也不起作用。
SelectedIndex
也设置在items listl之外。如果,则它应该是
ActivityList.SelectedIndex=ActivityList.items.Count-1
+1@dkozl,用于
所选的项目
        mycollection.GroupDescriptions.Clear();
        mycollection.GroupDescriptions.Add(new PropertyGroupDescription("PART"));
        datagrid_parts.ItemsSource = mycollection.View;
<ListBox>
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel Orientation="Vertical" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
</ListBox>