6

I wish to dynamically change the scroll position of a Silverlight ListBox from C#, and I need to know how to access the ScrollViewer element of a ListBox control from C#?

Thanks guys, Jeff

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
Yttrium
  • 2,057
  • 7
  • 25
  • 28

5 Answers5

5

From within a class that inherits from the ListBox class, you can use the Protected GetTemplateChild():

var myScrollviewer = myListBox.GetTemplateChild("ScrollViewer") as ScrollViewer;

If you want to access this from outside the ListBox, then exposing the ScrollViewer via a Property should work, again through inheritance.

CAVEAT: If you have set your own custom template, then this Scrollviewer may not exist. You can use the templates Scrollviewer name instead of the "ScrollViewer" in the method above.

Dan
  • 12,808
  • 7
  • 45
  • 54
  • GetTemplateChild shows to be a protected method. Is that new? because now it seems your solution won't work anymore. http://msdn.microsoft.com/en-us/library/system.windows.controls.control.gettemplatechild(v=VS.95).aspx – Matt.M Mar 10 '11 at 21:56
  • Not sure, but I guess you will have to create a property on an inheriting class. This is what I did in the end if I remember correctly; it was a custom listview anyway. – Dan Mar 11 '11 at 12:57
  • This actually does not work and should not be attempted. GetTemplateChild is a protected method. – Kevin Jun 07 '11 at 12:35
  • I don't understand why it should not be attempted. Will it hurt? Yes, it is a protected method, so therefore you can use it in any inheriting class. The question is whether you are trying to access it directly or not. The other answer with votes is also showing ways using inheritance. I will update my 2yo answer to appease. – Dan Jun 07 '11 at 14:45
  • The above didn't work for me either. I brought up this issue again in a [separate question](http://stackoverflow.com/questions/10293236/accessing-the-scrollviewer-of-a-listbox-from-c-sharp#comment13246045_10293236) and got some other suggestions which did work. – dharmatech Apr 24 '12 at 15:49
3

Good question. I didn't find a way to do it directly, but came fairly close by looking at the Silverlight Controls project (they use the scrollviewer on the items control in some of the classes). Here is how you can get it, but it requires a custom listbox:

public class TestBox : ListBox
{
    private ScrollViewer _scrollHost;

    protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
    {
        var itemsHost = VisualTreeHelper.GetParent(element) as Panel;

        for (DependencyObject obj = itemsHost; obj != item && obj != null; obj = VisualTreeHelper.GetParent(obj))
        {
            ScrollViewer viewer = obj as ScrollViewer;
            if (viewer != null)
            {
                _scrollHost = viewer;
                break;
            }
         }

        base.PrepareContainerForItemOverride(element, item);
    }
}

There might be another way to hook into that event (or another way to get that panel), If you look at the template for the ListBox you will see the scroll viewer is actually named "ScrollViewer", however the GetTemplateChild method is protected so you would still need to create a custom class.

MyKuLLSKI
  • 5,285
  • 3
  • 20
  • 39
Bryant
  • 8,660
  • 1
  • 33
  • 53
1

Let's make it easy... In your Listbox template, you might find the ScrollViewer Control. Add a Loaded Method for it, and you will get itself frome the sender arg.

private void ScrollViewer_Loaded(object sender, System.Windows.RoutedEventArgs e)
    {
        myScrollViewer = (sender as ScrollViewer);
    }

this works for me

Yop
  • 19
  • 2
0

You can call :

myListBox.ApplyTemplate();

to force the ListBox visual tree to be created, otherwise GetTemplateChild() will return Null if you attempt to access it immediatly.

This works well combined with "Erno de Weerd" explanation : inherit ListBox to be able to call GetTemplateChild() method.

I also tried :

  • to use ListBox extension method "GetScrollHost()" but it never worked for me (even after full page initialisations).
  • "FindName()", but it didn't work, even when i specified the ScrollViewer name into the ListBox Template.

Emmanuel (Silverlight 3)

-1
ScrollViewer scrollViewer = yourListBox.getScrollHost();

Is null if no datasourse set to the listbox, in my case it return properly UI Element only after below code executed

myListBox.ItemsSource = list;
Sergii
  • 9
  • 1