4

Been searching around the net for the answer but I haven't found anything that does this:

I want to change the exact position in a WPF-list iew programmatically. Some way of saying

ListView.Scrollposition.Y = some value;

The only thing I can find is to change the value to a object within the Listview, not specific coordinates. If anyone has some good articles or posts in this subject, I'd be very grateful!

Thanks.

Tokfrans
  • 1,939
  • 2
  • 24
  • 56

2 Answers2

7

There is no way of doing that using the ListView element. Instead, you need to access its ScrollViewer and then you can use the ScrollViewer.ScrollToVerticalOffset Method to set the vertical position of the ScrollViewer. You'll also need to use the ScrollViewer.VerticalOffset, ScrollViewer.VerticalOffset, ScrollViewer.ViewportHeight and ScrollViewer.ExtentHeight properties to gauge where you are in the ScrollViewer.

From the ScrollViewer Class page on MSDN:

The area that includes all of the content of the ScrollViewer is the extent. The visible area of the content is the viewport.

Finally, how do you get the ScrollViewer from the ListView? I can't guarantee that this will work on a ListView, but it does on a ListBox. you can use the VisualTreeHelper.GetChild Method to delve into the visual tree of the ListView and it should contain a Border and then the ScrollViewer, so you should be able to do something like this:

Border border = (Border)VisualTreeHelper.GetChild(YourListView, 0);
ScrollViewer scrollViewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;
if (scrollViewer != null)
{
    scrollViewer.ScrollToVerticalOffset(60.0);
}

If you do get an error with what the GetChild method returns, it'll be easy to adjust by debugging it. Just put a breakpoint there and see what each child type is and add another line with one of those elements... eventually, it should find the ScrollViewer. However, I think that that code should be fine.

Sheridan
  • 68,826
  • 24
  • 143
  • 183
  • Very in-depth answer, I'll have a look at the Scrollviewer class, almost knew it had to be it.. Thank you for this wonderful answer! :) – Tokfrans Jan 29 '14 at 21:43
5

If it's a ListView then first you'll need to find ScrollViewer:

private ScrollViewer FindScrollViewer(DependencyObject d)
{
   if (d is ScrollViewer)
      return d as ScrollViewer;

   for (int i = 0; i < VisualTreeHelper.GetChildrenCount(d); i++)
   {
      var sw = FindScrollViewer(VisualTreeHelper.GetChild(d, i));
      if (sw != null) return sw;
   }
   return null;
}

and when you find it then you can ScrollToVerticalOffset

var sw = FindScrollViewer(listView);
if (sw != null) sw.ScrollToVerticalOffset(x);
dkozl
  • 32,814
  • 8
  • 87
  • 89
  • 1
    No problem. You did not mention why you want to scroll but you may also want to look into [`ListBox.ScrollIntoView`](http://msdn.microsoft.com/en-us/library/system.windows.controls.listbox.scrollintoview(v=vs.110).aspx) which allows you to bring specific item into view – dkozl Jan 29 '14 at 21:50
  • Oh, sorry. I am trying to implement a kinetic-scrolling feature into my Listviews, so I really want a very precise scrolling instead of the item-by-item way (since that doesn't make sense for that purpose) – Tokfrans Jan 29 '14 at 21:55
  • Thanks, @dkozl. How would I implement the above in an MVVM app? – Alex Oct 27 '17 at 18:55