2013-06-05 191 views
9

我想滚动到视图中,以便垂直listivew中最后一项始终显示,但ListView.ScrollIntoView()从不起作用。为什么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);但没有什么工作。

请帮忙。这真的很烦人。在这种情况下文档isn't very helpful

回答

12

当方法需要项目对象时,您正在传入索引。试试这个来滚动到选定的项目。

ActivityList.ScrollIntoView(ActivityList.SelectedItem); 

如果你想滚动到最后一个项目,你可以使用这个

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

对不起上班,我忘了说,这是我想的第一件事情(按照文档)。那也行不通。 –

+1

'SelectedIndex'也设置在项目listl之外。如果,那么它应该是'ActivityList.SelectedIndex = ActivityList.Items.Count - 1' – dkozl

+2

+1 @dkozl'SelectedIndex'值。 Jase,如果仍然不起作用,请在'ScrollIntoView'方法之前尝试调用'ActivityList.UpdateLayout();'。 – keyboardP

1

要指定项目的索引和列表框预计项目本身。 尝试是这样的:

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

activities.Add(activity); 

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

这是一个ListView。我最初分配的实际对象(ListView.SelectedItem),但没有奏效。我忘了在我的问题中提出这个问题,因为我已经尝试了十几件事情来尝试并使其发挥作用。我实际上在这里处理一个ListView,而不是一个ListBox,但MSDN链接到ListView.ScrollIntoView()链接的ListBox页面。正如你可以从这里看到的:http://msdn.microsoft.com/en-us/library/system.windows.controls.listview.aspx –

8

它有事情做与内部列表表示,即项目尚未到位,当你调用ScrollIntoView().多次尝试后,这是我终于想出了这似乎工作:重视处理每一个ListBox/ListView:

​​

void YourList_Loaded(object sender, RoutedEventArgs e) { 
    if (YourList.SelectedItem != null) 
    YourList.ScrollIntoView(YourList.SelectedItem); 
} 

void YourList_SelectionChanged(object sender, SelectionChangedEventArgs e) { 
    if (YourList.SelectedItem != null) 
    YourList.ScrollIntoView(YourList.SelectedItem); 
} 

你不能没有的第二个处理程序。设置所选项目后,您不能立即致电ScrollIntoView(),但尚未准备就绪。您必须让列表在其实际更改项目时通知您。第一个处理程序取决于具体情况,如果您在初始加载列表内容后显示的选择有问题,则可能也需要它。

+1

这个解决方案适合我! – sharpguru

3

的问题ActivityList.ScrollIntoView(ActivityList.Items[ActivityList.Items.Count - 1]); 和similiar的“解决方案”,至少从什么我遇到了,就是当列表框包含相同的项目超过一次,它跳转到它找到的第一个,即最低指数。所以,它不关心你输入的物品的索引,它只是寻找那个物品并选择第一个物品。

我还没有找到一个解决的办法,但我考虑现在采取的办法是插入而不是添加物品。在原来的海报的情况下,我认为这将导致:

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

或可能:

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

导致每一个新的条目被插在上面,从而ScrollIntoView甚至不需要到叫做。

+0

这是我的问题,但我可以通过在课堂中包装我的字符串来解决它。 –

0

一个老的文章,但由于没有一个答案在这里工作了我的情况我想补充我的实现。 我发现这里的解决方案:https://social.msdn.microsoft.com/Forums/vstudio/en-US/8a745550-4360-4b53-85f5-032f8f46e2cc/listview-scrollintoview-not-working-with-a-observablecollection?forum=wpf][1]

((INotifyCollectionChanged)lvLogs.Items).CollectionChanged += ListView_CollectionChanged; 

private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
{ 
    ScrollToEnd(this.lvLogs); 
} 

private void ListView_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) 
     { 
      if ((e.Action == NotifyCollectionChangedAction.Add) && (e.NewItems != null)) 
      { 
       try 
       { 
        ScrollToEnd(this.lvLogs); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.ToString(), "Error updating list view", MessageBoxButton.OK, MessageBoxImage.Error); 
       } 

      } 
     } 

public void ScrollToEnd(ListView _ListView) 
{ 
    ScrollViewer _ScrollViewer = GetDescendantByType(_ListView, typeof(ScrollViewer)) as ScrollViewer; 
    _ScrollViewer.ScrollToEnd(); 
} 

public 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; 
} 

对我来说完美的作品。

0

我面临的问题是相似的。我以编程方式添加到列表框,并需要添加最后一个项目才能看到。搭售各种方法后,我发现下面是最简单和最

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

这是一个老的文章,但我已经在Windows商店应用同样的问题,发现了以下工作:

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

干杯, 保罗

0

只需拨打方法UpdateLayout请...

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

这将工作...

或者更简单的方法...只是编译应用程序:)而不会导致UpdateLayot()