簡體   English   中英

WPF訪問列表視圖代碼隱藏的滾動查看器

[英]WPF accessing scrollviewer of a listview codebehind

我需要從代碼隱藏訪問列表視圖的滾動查看器。 這是我的列表視圖的定義

<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>

我怎樣才能獲得滾動查看器?

謝謝

安德烈亞

有幾種方法可以獲取ScrollViewer 最簡單的解決方案是獲取ListView的第一個孩子的第一個孩子。 這意味着像這個答案中描述的那樣在這個 Border 中獲取BorderScrollViewer

// 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;

第二種方法是掃描所有孩子的遞歸以找到 ScrollViewer。 這在馬特漢密爾頓在這個問題的回答中有所描述。 您可以簡單地使用此函數來獲取ScrollViewer

ScrollViewer scrollViewer = GetChildOfType<ScrollViewer>(mylistview);

第二個解決方案更通用,如果編輯了ListView的模板,也可以使用。

使用 VisualTreeHelper 類訪問任何子控件。

您的案例的偽代碼:

 //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;
         }      
 }

我不知道您為什么要訪問scrollviewer,但它是一個附加屬性和附加屬性,您可以這樣設置: 如何在代碼后面訪問附加屬性?

我還建議使用 CollectionChanged 事件。 在此代碼中,在加載視圖模型后,將 CollectionChanged 事件處理程序添加到代碼隱藏中。 然后,每次集合更改時,我們都會滾動到列表視圖的底部。 這里有一個重要的點。 當我們的事件開始觸發時,列表視圖的滾動查看器子級可能尚未完全呈現。 因此,如果我們嘗試使用 VisualTreeHelper.GetChild 方法,我們將得到異常。 因此,我們必須首先嘗試獲取滾動查看器,然后如果尚不可用則忽略其定位。

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();
            }
        }
    }


    

LayoutUpdated之后應該可以訪問 Listview 的 ScrollViewer 。 您可以掛鈎LayoutUpdated ,然后從Visual tree獲取 if

 private static void ListView_LayoutUpdated(object sender, EventArgs e)
 {
    var listview = (ListView)sender;
    var viewer = listview.GetFirstChildOfType<ScrollViewer>();
 }

public static T GetFirstChildOfType<T>(this DependencyObject dependencyObject) where T : DependencyObject
    {
      if (dependencyObject == null)
      {
        return null;
      }

      for (var i = 0; i < VisualTreeHelper.GetChildrenCount(dependencyObject); i++)
      {
        var child = VisualTreeHelper.GetChild(dependencyObject, i);

        var result = (child as T) ?? GetFirstChildOfType<T>(child);

        if (result != null)
        {
          return result;
        }
      }

      return null;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM