WPF:确定面板是否对用户可见

4
我有一个WPF用户控件(myGraphicControl),在一个选项卡(WPF应用程序)中。
当窗体大小改变时,我会重新绘制myGraphicControl中的图形。
由于重绘操作是一个耗时操作,我只需要在可见选项卡中执行。
WPF(用户)控件如何检测它是否实际上“可见”?
PS.
通过“可见”,我指的是用户可以看到它。例如,如果一个可见的文本框位于当前不可见的选项卡中,则此文本框对用户不可见。

“visible” 是什么意思?是指在顶部,没有被任何方式遮挡吗? - Emond
我曾经遇到过同样的问题,但我已经解决了。我在这个帖子中写下了解决方案:https://dev59.com/nXI_5IYBdhLWcg3wHvQ5#42254899 - Ofer Barasofsky
3个回答

3

我认为这里没有快速解决方案,但是您可以使用UIElement.InputHitTest(Point)来尝试解决问题。

您可以进行类似以下的调用:

//get the coordinates of the top left corner of the child control within
//the parent
var childTopLeft = childControl.TranslatePoint(new Point(), parentControl);
//check whether or not the child control is returned when you request the element
//at that coordinate through hit testing
var isVisible = (parentControl.InputHitTest(childTopLeft) == childControl);

然而,我应该指出我自己并没有尝试过这个方法,并且它可能无法在以下情况下工作:

  • 透明元素 - 通常,透明背景会导致控件的命中测试传递给父级
  • 部分遮挡的元素 - 您一次只能测试一个点,因此如果您的子控件只有一部分可见,您将需要检查正确的点

2

我发现,虽然Steve的方法通常有效,但如果从子控件中间某个位置获取一个点,则其可靠性更高。我猜测,可能是布局舍入在某些情况下导致InputHitTest检查不太准确。因此,请将他的第一行更改为以下内容,那么你就成功了:

var childTopLeft = childControl.TranslatePoint(new Point(childControl.RenderSize.Width/2, childControl.RenderSize.Height/2), parentControl);

1

或许 UIElement.IsVisible 会有所帮助?它对选项卡内容很有效。 无论如何,您可以使用在这里描述的解决方案。

我还有一个解决方案。TabControl 的当前实现会从可视树中删除非活动选项卡。因此,确定元素是否可见的另一种方法是查找 PresentationSource。对于非活动选项卡的元素,PresentationSource 将为 null。


假设在这里提问之前,测试“IsVisible”是可以进行的第一件事情。我的元素始终是可见的,这意味着它没有被隐藏,但用户可能无法看到它,因为它位于“非活动”选项卡中。 - serhio
谢谢提供第二个链接。不幸的是,我的控件不在滚动视图中,而是在TabControl的选项卡中。 - serhio
1
好的,我也测试了一下。对于“不活动”选项卡中的元素,该属性为false。也许你应该重复一下你的测试? :) - Marat Khasanov
我修改了我的答案,添加了另一种解决方案 :) - Marat Khasanov
问题在于我使用了WindowsForm选项卡控件。我在一个Winforms应用程序中托管了一个WPF用户控件。因此,TabControl是WinForms的... - serhio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接