WPF实现ScrollViewer滚动到指定控件处

发布时间 - 2026-01-11 02:00:27    点击率:

在前端 UI 开发中,有时,我们会遇到这样的需求:在一个 ScrollViewer 中有很多内容,而我们需要实现在执行某个操作后能够定位到其中指定的控件处;这很像在 HTML 页面中点击一个链接后定位到当前网页上的某个 anchor。

要实现它,首先我们需要看 ScrollViewer 为我们提供的 API,其中并没有类似于 ScrollToControl 这样的方法;在它的几个以 ScrollTo 开头的方法中,最合适的就是 ScrollToVerticalOffset 这个方法了,这个方法接受一个参数,即纵向的偏移位置。那么,很重要的问题:我们怎么能得到要定位的那个控件在 ScrollViewer 中的位置呢?

在我之前写的这篇文章中:XAML: 获取元素的位置,有如何获到元素相对位置的介绍,建议大家先了解一下,其中使用了 Visual.TransformToVisual 方法等。当你理解了这篇文章后,再回过头来看本文后面的内容,就很容易了。

接下来,我们使用以下代码,即可实现上述需求:

// 获取要定位之前 ScrollViewer 目前的滚动位置
 var currentScrollPosition = ScrollViewer.VerticalOffset;
 var point = new Point(0, currentScrollPosition);

 // 计算出目标位置并滚动
 var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point);
 ScrollViewer.ScrollToVerticalOffset(targetPosition.Y);

另外,由于通常情况下,我们会采用 MVVM 模式,因此我们可以将上述代码封装成一个 Action,而避免在 Code-Behind 代码文件中添加上述代码。

新创建的名为 ScrollToControlAction 的 Action,在其中定义两个依赖属性 ScrollViewer 和 TargetControl,分别表示指定的要操作的 ScrollViewer 和要定位到的控件,然后将上述代码放到其 Invoke 方法中即可。由于 Action 并非本文主题,所以这里并不会展开太多的讲解,可以参考以下代码或本文后提供的 Demo 作进一步了解。

namespace ScrollTest
{
 /// <summary>
 /// 在 ScrollViewer 中定位到指定的控件
 /// 说明:目前支持的是垂直滚动
 /// </summary>
 public class ScrollToControlAction : TriggerAction<FrameworkElement>
 {
 public static readonly DependencyProperty ScrollViewerProperty =
 DependencyProperty.Register("ScrollViewer", typeof(ScrollViewer), typeof(ScrollToControlAction), new PropertyMetadata(null));

 public static readonly DependencyProperty TargetControlProperty =
 DependencyProperty.Register("TargetControl", typeof(FrameworkElement), typeof(ScrollToControlAction), new PropertyMetadata(null));

 /// <summary>
 /// 目标 ScrollViewer
 /// </summary>
 public ScrollViewer ScrollViewer
 {
 get { return (ScrollViewer)GetValue(ScrollViewerProperty); }
 set { SetValue(ScrollViewerProperty, value); }
 }

 /// <summary>
 /// 要定位的到的控件
 /// </summary>
 public FrameworkElement TargetControl
 {
 get { return (FrameworkElement)GetValue(TargetControlProperty); }
 set { SetValue(TargetControlProperty, value); }
 }

 protected override void Invoke(object parameter)
 {
 if (TargetControl == null || ScrollViewer == null)
 {
 throw new ArgumentNullException($"{ScrollViewer} or {TargetControl} cannot be null");
 }

 // 检查指定的控件是否在指定的 ScrollViewer 中
 // TODO: 这里只是指定离它最近的 ScrollViewer,并没有继续向上找
 var container = TargetControl.FindParent<ScrollViewer>();
 if (container == null || container != ScrollViewer)
 {
 throw new Exception("The TargetControl is not in the target ScrollViewer");
 }

 // 获取要定位之前 ScrollViewer 目前的滚动位置
 var currentScrollPosition = ScrollViewer.VerticalOffset;
 var point = new Point(0, currentScrollPosition);

 // 计算出目标位置并滚动
 var targetPosition = TargetControl.TransformToVisual(ScrollViewer).Transform(point);
 ScrollViewer.ScrollToVerticalOffset(targetPosition.Y);
 }
 }
}

其使用方法如下:

<Button>
 <i:Interaction.Triggers>
  <i:EventTrigger EventName="Click">
  <local:ScrollToControlAction ScrollViewer="{Binding ElementName=s}" TargetControl="{Binding ElementName=txtSectionC}" />
  </i:EventTrigger>
 </i:Interaction.Triggers>
</Button>

至此,结合 Action,我们以非常灵活的方式实现了本文所提出的需求。

 源码下载

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# WPF  # ScrollViewer  # 滚动  # WPF自定义控件和样式之自定义按钮(Button)  # WPF如何自定义TabControl控件样式示例详解  # 超炫酷的WPF实现Loading控件效果  # WPF的ListView控件自定义布局用法实例  # 在WPF中动态加载XAML中的控件实例代码  # C# 使用WPF 用MediaElement控件实现视频循环播放  # WPF自定义TreeView控件样式实现QQ联系人列表效果  # WPF实现带全选复选框的列表控件  # WPF开发技巧之花式控件功能扩展详解  # 这篇文章  # 计算出  # 的是  # 几个  # 在我  # 太多  # 当你  # 中有  # 很容易  # 我们可以  # 很重要  # 类似于  # 很像  # 最合适  # 大家多多  # 源码下载  # 再回  # 方法如下  # 实现了  # 情况下 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 如何获取PHP WAP自助建站系统源码?  Laravel怎么使用Intervention Image库处理图片上传和缩放  Laravel如何使用Collections进行数据处理?(实用方法示例)  Internet Explorer官网直接进入 IE浏览器在线体验版网址  潮流网站制作头像软件下载,适合母子的网名有哪些?  Laravel如何使用Telescope进行调试?(安装和使用教程)  PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】  北京网站制作的公司有哪些,北京白云观官方网站?  如何确保西部建站助手FTP传输的安全性?  Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践  如何选择可靠的免备案建站服务器?  如何在阿里云ECS服务器部署织梦CMS网站?  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  详解Huffman编码算法之Java实现  Mybatis 中的insertOrUpdate操作  Claude怎样写约束型提示词_Claude约束提示词写法【教程】  如何在服务器上配置二级域名建站?  Swift开发中switch语句值绑定模式  魔毅自助建站系统:模板定制与SEO优化一键生成指南  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?  谷歌Google入口永久地址_Google搜索引擎官网首页永久入口  Win11怎么关闭资讯和兴趣_Windows11任务栏设置隐藏小组件  详解阿里云nginx服务器多站点的配置  Laravel Octane如何提升性能_使用Laravel Octane加速你的应用  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  简历在线制作网站免费版,如何创建个人简历?  JavaScript中的标签模板是什么_它如何扩展字符串功能  Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控  Laravel如何实现URL美化Slug功能_Laravel使用eloquent-sluggable生成别名【方法】  uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址  晋江文学城电脑版官网 晋江文学城网页版直接进入  米侠浏览器网页背景异常怎么办 米侠显示修复  Laravel如何使用withoutEvents方法临时禁用模型事件  ,怎么在广州志愿者网站注册?  Laravel怎么在Blade中安全地输出原始HTML内容  WordPress 子目录安装中正确处理脚本路径的完整指南  如何用好域名打造高点击率的自主建站?  如何用PHP工具快速搭建高效网站?  如何在万网自助建站平台快速创建网站?  Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱动更新修复【详解】  如何批量查询域名的建站时间记录?  大型企业网站制作流程,做网站需要注册公司吗?  实现点击下箭头变上箭头来回切换的两种方法【推荐】  如何自定义safari浏览器工具栏?个性化设置safari浏览器界面教程【技巧】  linux写shell需要注意的问题(必看)  lovemo网页版地址 lovemo官网手机登录  详解jQuery中基本的动画方法  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  大连网站制作公司哪家好一点,大连买房网站哪个好?