[英]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 中獲取Border
和ScrollViewer
:
// 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.