从折叠的列表框中获取滚动查看器

Getting scrollviewer from Collapsed ListBox

我正在努力从折叠的列表框中获取 ScrollViewer。 它将是可见的,我已经尝试过:

-加载事件后:

        documentListBox.Loaded += (sender, e) =>
        {
            var scroller = documentListBox.Template.FindName("Scroller", documentListBox);
            var scroller1 = LogicalTreeHelper.GetParent(documentListBox);
            var scroller2 = VisualTreeHelper.GetParent(documentListBox);
            var scroller3 = Extensions.GetDescendantByType(documentListBox, typeof(ScrollViewer)) as ScrollViewer;
            var scroller4 = documentListBox.Template.FindName("ScrollViewer", documentListBox) as ScrollViewer;
        }


      ----------------Extensions.GetDescendantByType:----------------
   public static 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;
    }

-IsVisibleChanged 后:

    documentListBox.IsVisibleChanged+=VisibilityChanged

    VisibilityChanged(){
            var scroller = Extensions.GetDescendantByType(documentListBox, typeof(ScrollViewer)) as ScrollViewer;
            var scroller1 = documentListBox.Template.FindName("ScrollViewer", documentListBox) as ScrollViewer;
            var scroller2 = VisualTreeHelper.GetParent(documentListBox);
            var scroller3 = LogicalTreeHelper.GetParent(documentListBox);
     }

还尝试覆盖 ListBox 并在这两种情况下添加 属性:

       public ScrollViewer Scroller
    {
        get
        {
            return GetTemplateChild("ScrollViewer") as ScrollViewer;
        }
    }

所有这些要么给了我别的东西,要么 null。 想知道怎么称呼吗?或者我可以在哪里访问它。

通过添加新模板找到它:

        <ListBox.Template>
        <ControlTemplate>
            <ScrollViewer x:Name="Scroller">
                <VirtualizingStackPanel Orientation="Vertical" IsItemsHost="True"/>
            </ScrollViewer>
        </ControlTemplate>
    </ListBox.Template>

然后在我的代码隐藏中覆盖 OnRender:

protected override void OnRender(DrawingContext dc)
{
    base.OnRender(dc);
    var scrollviewer = (documentListView.Template.FindName("Scroller", documentListView)) as ScrollViewer;

还必须更改可见性设置:

Visibility="{Binding ViewIsVisible, Converter={Panels:BoolToVisibilityConverter}, FallbackValue=Visible}"

在我的 VM 中将此设置为 false 会使视图在渲染后崩溃。

原因是 ListBox/ListView 在可见之前不会渲染它们的 Template(效率更高)。