WPF accessing scrollviewer of a listview codebehind

这一生的挚爱 提交于 2021-01-27 05:27:19

问题


I need to access the scrollviewer of a listview from the codebehind. here is the definition of my listview

<ListView Grid.Row="1" ItemsSource="{Binding Path=SpecList, UpdateSourceTrigger=PropertyChanged}"  
                            Name="mylistview"
                            ItemTemplate="{StaticResource SpecElementTemplate}"
                            Background="{StaticResource EnvLayout}"
                            ScrollViewer.HorizontalScrollBarVisibility="Visible"
                            ScrollViewer.VerticalScrollBarVisibility="Disabled"
                            ItemContainerStyle="{StaticResource MyStyle}"
                            BorderBrush="Blue"
                            BorderThickness="20"
                            Margin="-2">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListView.ItemsPanel>
</ListView>

How can I get the scrollviewer?

Thank you

Andrea


回答1:


There are several ways to get the ScrollViewer. Simplest solution is to get the the first child of the first child of the ListView. This means get the Border and the ScrollViewer inside this Border like described in this answer:

// Get the border of the listview (first child of a listview)
Decorator border = VisualTreeHelper.GetChild(mylistview, 0) as Decorator;

// Get scrollviewer
ScrollViewer scrollViewer = border.Child as ScrollViewer;

A second way is to scan all childrens recursive to find the ScrollViewer. This is described in the answer by Matt Hamilton in this question. You can simply use this function to get the ScrollViewer.

ScrollViewer scrollViewer = GetChildOfType<ScrollViewer>(mylistview);

This second solution is much more generic and will also work if the template of your ListView was edited.




回答2:


Use VisualTreeHelper class to access any child control.

Psudeo code to your case:

 //Declare a scroll viewer object.
 ScrollViewer  sViewer = default(ScrollViewer );

 //Start looping the child controls of your listview.
 for (int i = 0; i < VisualTreeHelper.GetChildrenCount(YOUR_LISTVIEW_OBJECT.VisualParent ); i++)
 {
        // Retrieve child visual at specified index value.
        Visual childVisual = (Visual)VisualTreeHelper.GetChild(YOUR_LISTVIEW_OBJECT.VisualParent , i);

        ScrollViewer sViewer = childVisual as ScrollViewer;

        //You got your scroll viewer. Stop looping.
         if (sViewer != null)
         {
             break;
         }      
 }



回答3:


I also suggest using the CollectionChanged event. In this code, the CollectionChanged event handler is added to the codebehind after the view model has been loaded. Then, each time the collection changes we scroll to the bottom of the listview. Here is an important point. The scrollviewer child of the list view might not yet be completely rendered when our events start firing. Hence we will get exceptions if we try to use the VisualTreeHelper.GetChild method. So, we have to first attempt to get the scrollviewer and then ignore its positioning if it is not yet available.

private void ReceivedItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        // Make sure the items source property in the viewmodel has some items
        if (myViewModel.ReceivedItems.Count > 0)
        {
            var aScrollViewer = RcvdListView.GetChildOfType<ScrollViewer>();
            // Make sure the scrollviewer exists before trying to position it
            if (aScrollViewer != null)
            {
                aScrollViewer.ScrollToBottom();
            }
        }
    }


    


来源:https://stackoverflow.com/questions/43053345/wpf-accessing-scrollviewer-of-a-listview-codebehind

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!