I'm trying to see if one of my controls is Visible (to put focus on it), but when I check the Visibility property, it is always Visible, even if an ancestor is hidden. How can I tell if a given control is actually visible (even if it's virtualized or off-screen)?
<StackPanel x:Name="StackPanelThatGetsHidden" Visibility="Hidden">
<Button x:Name="TheButton">Focus me</Button>
</StackPanel>
TheButton().Visibility() // => Visible
TheButton().Focus() // => false, since the button is actually invisible
Unfortunately, there is no easy way to detect if any parent item is hidden (non-Visible). You'll have to loop through the visual tree:
// NOTE: this does not check a bajillion other properties; a control can still be off-screen,
// virtualized, etc. This only checks ancestor visibility.
bool IsControlVisible(winrt::FrameworkElement const& control)
{
auto currentElement = control;
while (currentElement)
{
if (currentElement.Visibility() != winrt::Visibility::Visible)
{
return false;
}
currentElement = winrt::VisualTreeHelper::GetParent(currentElement).try_as<winrt::FrameworkElement>();
}
return true;
}
See Proposal: Add a way to track effective visibility of a control, a GitHub issue requesting similar functionality be added to UWP/WinUI.