简体   繁体   English

如何在Silverlight / C#中访问ListBox控件的ScrollViewer元素?

[英]How do you access the ScrollViewer element of a ListBox control in Silverlight/C#?

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#? 我希望从C#动态更改Silverlight ListBox的滚动位置,我需要知道如何从C#访问ListBox控件的ScrollViewer元素?

Thanks guys, Jeff 谢谢你们,杰夫

From within a class that inherits from the ListBox class, you can use the Protected GetTemplateChild(): 从继承自ListBox类的类中,您可以使用受保护的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. 如果要从ListBox外部访问它,那么通过属性公开ScrollViewer应该再次通过继承。

CAVEAT: If you have set your own custom template, then this Scrollviewer may not exist. CAVEAT:如果您已设置自己的自定义模板,则此Scrollviewer可能不存在。 You can use the templates Scrollviewer name instead of the "ScrollViewer" in the method above. 您可以在上面的方法中使用模板Scrollviewer名称而不是“ScrollViewer”。

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). 我没有找到直接做到这一点的方法,但是通过查看Silverlight Controls项目(他们在某些类中使用项目控件上的scrollviewer)来得到相当接近。 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. 可能有另一种方法来挂钩该事件(或另一种方式来获取该面板),如果您查看ListBox的模板,您将看到滚动查看器实际上被命名为“ScrollViewer”,但GetTemplateChild方法受到保护,因此您仍然需要创建一个自定义类。

Let's make it easy... In your Listbox template, you might find the ScrollViewer Control. 让我们轻松一下......在列表框模板中,您可能会找到ScrollViewer Control。 Add a Loaded Method for it, and you will get itself frome the sender arg. 为它添加一个加载方法,你将从发送者arg得到自己。

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

this works for me 这对我有用

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. 强制创建ListBox可视化树,否则如果您尝试立即访问它,GetTemplateChild()将返回Null。

This works well combined with " Erno de Weerd " explanation : inherit ListBox to be able to call GetTemplateChild() method. 这与“ Erno de Weerd ”解释很好地结合:继承ListBox以便能够调用GetTemplateChild()方法。

I also tried : 我也尝试过:

  • to use ListBox extension method "GetScrollHost()" but it never worked for me (even after full page initialisations). 使用ListBox扩展方法“GetScrollHost()”但它从来没有为我工作(即使在整页初始化后)。
  • "FindName()", but it didn't work, even when i specified the ScrollViewer name into the ListBox Template. “FindName()”,但它不起作用,即使我将ScrollViewer名称指定为ListBox模板。

Emmanuel (Silverlight 3) Emmanuel(Silverlight 3)

ScrollViewer scrollViewer = yourListBox.getScrollHost();

如果没有数据集设置到列表框,则为null,在我的情况下,只有在执行下面的代码后才能正确返回UI元素

myListBox.ItemsSource = list;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM