[英]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.