如何检测控件在屏幕上是否可见
本文关键字:屏幕 是否 控件 何检测 检测 | 更新日期: 2023-09-27 17:50:21
我有一个Panorama
控件,它有三个项目:
<phone:Panorama>
<phone:PanoramaItem>
</phone:PanoramaItem>
<phone:PanoramaItem>
</phone:PanoramaItem>
<phone:PanoramaItem Header="third item" Orientation="Horizontal">
<Grid>
<StackPanel Margin="0,4,16,0" Orientation="Vertical" VerticalAlignment="Top">
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal">
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Orientation="Horizontal" Margin="0,12,0,0">
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="#FFFFC700" Height="173" Width="173" Margin="12,0,0,0"/>
<Border Background="Black" Height="173" Width="173" Margin="12,0,0,0"/>
</StackPanel>
</StackPanel>
</Grid>
</phone:PanoramaItem>
</phone:Panorama>
我怎么知道最后的Border
与黑色背景是在屏幕上,并为用户可见?因为它是一个水平的PanoramaItem
,我不能依靠全景的SelectedIndex
。任何建议吗?
如果你只是想检查一个元素是否在屏幕边界内,你可以使用VisualTreeHelper,像这样:
Rect screenBounds = new Rect(0, 0, Application.Current.Host.Content.ActualWidth, Application.Current.Host.Content.ActualHeight);
if (VisualTreeHelper.FindElementsInHostCoordinates(screenBounds, myPanorama).Contains(elementToCheck))
Debug.WriteLine("Element is now visible");
else
Debug.WriteLine("Element is no longer visible");
我对XAML做了两个更改(只是为了简化示例),首先我将Panorama
:
命名为<phone:Panorama x:Name="myPanorama">
其次,我还命名了Border
元素,你要检查的可见性:
<Border x:Name="elementToCheck" Background="Black" Height="173" Width="173" Margin="12,0,0,0"/>
如果你还想在一个事件中检查它,当全景滚动正在改变它似乎变得有点困难,因为ManipulationDelta
事件不工作,如果一个控件在其他控件之下。一种解决方案是在每次镜框报告触摸时进行检查。这是通过以下方式完成的:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
Touch.FrameReported += Touch_FrameReported;
}
private void Touch_FrameReported(object sender, TouchFrameEventArgs e)
{
// This is the same code as above
Rect screenBounds = new Rect(0, 0, Application.Current.Host.Content.ActualWidth, Application.Current.Host.Content.ActualHeight);
if (VisualTreeHelper.FindElementsInHostCoordinates(screenBounds, myPanorama).Contains(elementToCheck))
Debug.WriteLine("Element is now visible");
else
Debug.WriteLine("Element is no longer visible");
}
您还需要VisualTreeHelper
和Touch
的这两个using指令:
using System.Windows.Media;
using System.Windows.Input;
不幸的是,我现在想不出一个更简单的解决方案。
编辑:对于事件来说,这还远远不够完美,例如,如果全景被程序化地"平移",或者当它抓拍时,它不会给出预期的结果。问题是全景是建立在PanningLayer
, PanningTitleLayer
, PanningBackgroundLayer
之上的,而不是ScrollViewer
,所以没有ScrollBar
,这意味着没有Scroll
事件:(
一种解决方案是使用计时器定期检查它是否可见,但这也是一种难看的解决方案。