在前端 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开发技巧之花式控件功能扩展详解
# 这篇文章
# 计算出
# 的是
# 几个
# 在我
# 太多
# 当你
# 中有
# 很容易
# 我们可以
# 很重要
# 类似于
# 很像
# 最合适
# 大家多多
# 源码下载
# 再回
# 方法如下
# 实现了
# 情况下
相关文章:
香港服务器租用费用高吗?如何避免常见误区?
图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?
个人网站制作流程图片大全,个人网站如何注销?
如何快速启动建站代理加盟业务?
建站之星CMS建站配置指南:模板选择与SEO优化技巧
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
中山网站推广排名,中山信息港登录入口?
宝塔Windows建站如何避免显示默认IIS页面?
香港服务器网站卡顿?如何解决网络延迟与负载问题?
建站之星在线客服如何快速接入解答?
网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?
建站之星logo尺寸如何设置最合适?
太原网站制作公司有哪些,网约车营运证查询官网?
如何彻底卸载建站之星软件?
怎么制作一个起泡网,水泡粪全漏粪育肥舍冬季氨气超过25ppm,可以有哪些措施降低舍内氨气水平?
详解免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
大型企业网站制作流程,做网站需要注册公司吗?
南宁网站建设制作定制,南宁网站建设可以定制吗?
b2c电商网站制作流程,b2c水平综合的电商平台?
设计网站制作公司有哪些,制作网页教程?
MySQL查询结果复制到新表的方法(更新、插入)
建站主机如何安装配置?新手必看操作指南
*服务器网站为何频现安全漏洞?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
如何通过VPS建站实现广告与增值服务盈利?
如何快速登录WAP自助建站平台?
常州企业建站如何选择最佳模板?
c# Task.ConfigureAwait(true) 在什么场景下是必须的
c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗
活动邀请函制作网站有哪些,活动邀请函文案?
如何在云指建站中生成FTP站点?
制作网页的网站有哪些,电脑上怎么做网页?
建站之星伪静态规则如何设置?
如何在Ubuntu系统下快速搭建WordPress个人网站?
如何彻底删除建站之星生成的Banner?
C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换
我的世界制作壁纸网站下载,手机怎么换我的世界壁纸?
一键网站制作软件,义乌购一件代发流程?
Android使用GridView实现日历的简单功能
如何用腾讯建站主机快速创建免费网站?
宝塔面板如何快速创建新站点?
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
如何基于云服务器快速搭建网站及云盘系统?
建站之家VIP精选网站模板与SEO优化教程整合指南
大学网站设计制作软件有哪些,如何将网站制作成自己app?
西安大型网站制作公司,西安招聘网站最好的是哪个?
北京网站制作公司哪家好一点,北京租房网站有哪些?
为什么Go需要go mod文件_Go go mod文件作用说明
建站之星下载版如何获取与安装?
*请认真填写需求信息,我们会在24小时内与您取得联系。