需求

有一个ListView控件,希望能给ListView控件内部的ScrollViewer控件添加一个事件。

解决

方法1 通过模板解决**

1.为ListView添加模板

image.png

2.直接为内部的ScrollViewer添加事件绑定

image.png

  1. <ScrollViewer Padding="{TemplateBinding Padding}" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}" MouseUp="ScrollViewer_MouseUp">
  2. <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
  3. </ScrollViewer>

添加的代码为MouseUp="ScrollViewer_MouseUp"

3.向事件处理器中添加代码,完成

private void ScrollViewer_MouseUp(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("Test");
}

image.png
**

方法2 通过VisualTreeTreeHelper,利用索引解决

1.简介

我们在方法1中创建的模板,其中也是由若干控件组成的。这些控件构成的树称为VisualTree。我们可以通过VisualTreeHelper这个类来访问树上的成员。
主要用得到的是以下两个方法:

2.获取组件并添加事件处理器,完成

通过方法1中的操作,我们可以看到一个ListView中的结构是如何的:
image.png
也就是说,ListView内有一个名字为bd的ListBoxChrome,ListBoxChrome内部才是我们想要操作的ScrollViewer。每一层中的子控件都只有一个,所以操作起来也会比较便捷了。

//获取ListView中的ListBoxChrome
var listBoxChrome = VisualTreeHelper.GetChild(testListView, 0) as ListBoxChrome;

//获取ListView中的ScrollViewer
var scrollViewer = VisualTreeHelper.GetChild(listBoxChrome, 0) as ScrollViewer;

//为ScrollViewer添加事件处理器
scrollViewer.MouseUp += ScrollViewer_MouseUp;

事件处理器与方法1相同,就不赘述了。

效果:
image.png

方法3 通过VisualTreeHelper,利用在模板中为控件添加名称的方法解决

在这个例子中,控件内部的VisualTree结构比较简单,所以处理起来也很简单。如果结构比较复杂的时候,就需要涉及到校验组件的类型等方式来找到自己想要的内容了。
这种时候也可以选择在模板中为控件添加Name,这样可以用通过Name属性来找到指定的控件。

1.添加名称

在模板中,为内部的ScrollViewer添加x:Name="innerScrollViewer"Attribute:

<ScrollViewer x:Name="innerScrollViewer" Padding="{TemplateBinding Padding}" Style="{DynamicResource {x:Static GridView.GridViewScrollViewerStyleKey}}">
    <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</ScrollViewer>

2.通过代码获取

//通过名字获取
var scrollViewer = testListView.Template.FindName("innerScrollViewer",testListView) as ScrollViewer;

//为ScrollViewer添加事件
scrollViewer.MouseUp += ScrollViewer_MouseUp;

事件处理器的代码以及效果都一样,同样不再写出来了。