title author date CreateTime categories
WPF 如何判断一个控件在滚动条的里面是用户可见
lindexi
2019-4-29 9:42:2 +0800
2019-4-29 9:14:2 +0800
WPF

我有一个控件,这个控件放在滚动条里面,如果在滚动条滚动到这个控件可以被用户看见的时候,我能知道这个事件,或从什么时机可以拿到用户可以看见的范围修改?

昨天星期八再娶你 大佬问我如何判断在滚动条内可以看到某个元素,他需要在滚动条里面放一个视频播放器,在用户看不到这个播放器的时候自动停下这个播放器

在 WPF 可以通过 ScrollChanged 拿到当前的滚动到哪同时拿到滚动条可见的宽度和高度

在 ScrollChangedEventArgs 提供了多个属性用于拿到当前的滚动条的可见的宽度和高度,滚动条的水平移动和垂直的移动,具体请看下图

在用户修改外层控件的宽度或高度让滚动条的高度或宽度进行修改的时候,可以从 ViewportWidthChange 和 ViewportHeightChange 属性知道滚动条的可视宽度和高度修改了多少

在用户修改滚动条里面的控件的宽度或高度的时候,可以从 ExtentWidthChange 等属性知道用户修改了多少

那么如果判断某个控件在滚动条可见内就可以拿到某个控件的外接矩形和滚动条可见大小进行矩形判断,请看下图

那么如何拿到一个控件的外接矩形?首先需要知道这个控件在外层的垂直或水平偏移,也就是这个控件在外层控件的左上角坐标是多少,然后还需要知道这个控件的宽度和高度,这样就可以知道这个控件的外接矩形,拿到一个元素在外层控件的左上角坐标可以通过拿到这个控件的(0,0) 坐标转换到外层控件,计算出这个坐标是相对外层控件的大小

例如我有一个控件是 control 他的外层控件是 StackPanel 通过下面代码就可以看到控件的左上角的大小

            var top = control.TranslatePoint(new Point(), StackPanel);

我拿到了左上角还需要拿到控件的宽度和高度才能计算出矩形,可以使用下面代码

            // 控件的宽度和高度
var controlBounds = new Rect(top, control.DesiredSize);

此时计算滚动条的用户可见的大小,通过滚动条的水平和垂直移动加上宽度和高度,请看代码

    var viewBounds = new Rect(new Point(e.HorizontalOffset, e.VerticalOffset), new Size(e.ViewportWidth, e.ViewportHeight));

判断 controlBounds 和 viewBounds 是否相交就可以知道用户是否可以看到这个控件,当然如果是想要判断用户可以完全看到这个控件,就是判断滚动条是否完全显示里面的控件

            if (viewBounds.Contains(controlBounds))
{
Debug.WriteLine("控件完全显示");
}
else if (viewBounds.IntersectsWith(controlBounds))
{
Debug.WriteLine("用户可以看到控件");
}

下面是我实际写的代码

我在滚动添加了一个控件,在里面添加了很多文本,其中有一个是歪楼的文本

        <ScrollViewer ScrollChanged="ScrollViewer_OnScrollChanged">
<StackPanel x:Name="StackPanel">
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock x:Name="TextBlock" Text="歪楼"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
<TextBlock Text="123"></TextBlock>
</StackPanel>
</ScrollViewer>

我需要在歪楼的文本被用户看到的时候输出,于是我就在后台代码通过本文上面提供的方法拿到这个元素的矩形判断

        private void ScrollViewer_OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
UIElement control = TextBlock; var top = control.TranslatePoint(new Point(), StackPanel);
// 控件的宽度和高度
var controlBounds = new Rect(top, control.DesiredSize); // 用户可以看到的大小
var viewBounds = new Rect(new Point(e.HorizontalOffset, e.VerticalOffset),
new Size(e.ViewportWidth, e.ViewportHeight)); if (viewBounds.IntersectsWith(controlBounds))
{
Debug.WriteLine("歪楼");
}
else
{
Debug.WriteLine("不歪楼");
}
}

代码放在github

2019-4-29-WPF-如何判断一个控件在滚动条的里面是用户可见的更多相关文章

  1. 2019-11-29-win10-uwp-如何判断一个控件在滚动条的里面是用户可见

    原文:2019-11-29-win10-uwp-如何判断一个控件在滚动条的里面是用户可见 title author date CreateTime categories win10 uwp 如何判断一 ...

  2. 2019-4-29-win10-uwp-如何判断一个控件在滚动条的里面是用户可见

    title author date CreateTime categories win10 uwp 如何判断一个控件在滚动条的里面是用户可见 lindexi 2019-04-29 10:40:33 + ...

  3. WPF中得到一个控件相对其他控件的坐标

    加入想得到按钮btnTest左上角相对于主窗体winTest的坐标,可以用如下方法:btnTest.TranslatePoint(new Point(0, 0), winTest)这个方法返回一个Po ...

  4. WPF中的ControlTemplate(控件模板)(转)

    原文地址 http://www.cnblogs.com/zhouyinhui/archive/2007/03/28/690993.html WPF中的ControlTemplate(控件模板)     ...

  5. WPF基础篇之控件模板(ControlTemplate)

    WPF中每一个控件都有一个默认的模板,该模板描述了控件的外观以及外观对外界刺激所做出的反应.我们可以自定义一个模板来替换掉控件的默认模板以便打造个性化的控件. 与Style不同,Style只能改变控件 ...

  6. WPF中的ControlTemplate(控件模板)

    原文:WPF中的ControlTemplate(控件模板) WPF中的ControlTemplate(控件模板)                                             ...

  7. [转]WPF中的ControlTemplate(控件模板)

    WPF中的ControlTemplate(控件模板)                                                                           ...

  8. WPF 使用鼠标拖动一个控件的实现[2018.7.15]

    原文:WPF 使用鼠标拖动一个控件的实现[2018.7.15] Q:已经把一个Shape和一个TextBlock组合起来放到了一个Grid中,现在想要实现用鼠标拖动这个Grid到任意位置的功能,如何做 ...

  9. WPF自定义选择年月控件详解

    本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下 封装了一个选择年月的控件,XAML代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...

随机推荐

  1. 4.2.1 Vector bit-select and part-select addressing

    Frm:IEEE Std 1364™-2001, IEEE Standard Verilog® Hardware Description Language Bit-selects extract a ...

  2. 2019杭电多校第三场hdu6608 Fansblog(威尔逊定理)

    Fansblog 题目传送门 解题思路 Q! % P = (P-1)!/(P-1)...(Q-1) % P. 因为P是质数,根据威尔逊定理,(P-1)!%P=P-1.所以答案就是(P-1)((P-1) ...

  3. 牛客练习赛48 D 小w的基站网络

    链接:https://ac.nowcoder.com/acm/contest/923/D来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  4. 41-Ubuntu-用户管理-06-su切换用户

    su 切换用户 序号 命令 作用 说明 01 su - 用户名 切换用户,并且切换家目录 '-'可以切换到用户家目录,否则保持位置不变 02 exit 退出当前登录账户 返回上一级用户 图:su与ex ...

  5. win10命令行kill进程

    1. 查:netstat -ano | findstr "8080" 2. 杀:taskkill -PID 8082 -F

  6. linux 7 添加永久路由方法

    linux 7 添加永久路由 用route命令添加 仅仅是当前状态下生效,一旦重启就会失效. 所以要在/etc/sysconfig/network-scripts/这个路径下添加一个文件route-{ ...

  7. elasticsearch 父子文档(十一)

    说明 需求 一个产品多个区域销售 每个区域有自己的价格, 方式1冗余行,a 产品分别在  area1 area2 area3区域销售 a产品就会生成3条产品数据 搜索id去重就行了,但是问题就是 聚合 ...

  8. 图(graph)

    一.非线性结构:图 图由顶点集V,集合规模为n,在n个顶点之间可能存在对应关系,我们用连边来描述这种,即边E,规模为e. 邻接关系:顶点与顶点之间的关系:关联关系:顶点与它相连的边的关系.序列结构(v ...

  9. K8S命令的梳理

    kubectl是一个基础的K8S集群管理命令,可以实现对K8S资源的查询,创建,删除,更新,回退等各种各样的操作.由于其复杂的功能体系,命令灵活度又高,因此需要进行常见的一些命令和使用场景的梳理. 1 ...

  10. vue之自定义插件

    1.插件的作用 插件通常会为 Vue 添加全局功能,一般是添加全局方法/全局指令/过滤器等 Vue 插件有一个公开方法 install ,通过 install 方法给 Vue 添加全局功能 通过全局方 ...