I have a flyout with a cancel button, where I want the "Cancel" click handler to Hide() the parent flyout. The code segment (below) is part of a ListBoxItem, so I can't reference the flyout by x:name="flyout_name".
This means I need to traverse the Visual Tree Hierarchy, but I'm having trouble accessing the parent Controls::Flyout object.
<Button x:Name="DeleteColButton" Content="Delete">
<Button.Flyout>
<Flyout>
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="ScrollViewer.HorizontalScrollMode" Value="Disabled"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
<Setter Property="IsTabStop" Value="True"/>
<Setter Property="TabNavigation" Value="Cycle"/>
</Style>
</Flyout.FlyoutPresenterStyle>
<StackPanel>
<TextBlock TextWrapping="Wrap" Text="Are you sure?"/>
<Button Click="DeleteColClickHandler">Yes</Button>
<Button Click="DeleteColCancelClickHandler">Cancel</Button>
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
I can go from the "Cancel" Button to the top-level stackpanel in the flyout, but the next level up is neither Controls::Flyout nor Controls::FlyoutPresenter. I can call panel.GetParent() 11 times after "escaping" the top-level stackpanel, and none of those DependencyObjects show up as Flyout, FlyoutPresenter, StackPanel, ListBoxItem, or ListBox. Is the visual hierarchy of Flyout somehow disconnected from the hierarchy I'm tracing through the XAML?
I've heard that Flyout doesn't have an associated DependencyObject in the visual tree.. Is this really the case? If I try to go top-down, how would I find the DependencyObject of a ListBoxItem?
Should I switch to Dialog?
Edit: I tried to get access to the button for ( Button().Flyout().Hide() ) from the ListBoxItem, but it proved too difficult.
However, using GetOpenPopups() to get the list of open popups - and closing them all - seemed to work. Thank you!
I can go from the "Cancel" Button to the top-level stackpanel in the flyout, but the next level up is neither Controls::Flyout nor Controls::FlyoutPresenter.
For explain this, you need check this document first,
Popups don't exist in the conventional XAML visual tree that begins from the root visual, although they are associated with the app main window. Unless your app maintains a list of all the Popup elements you've created as well as a status (the IsOpen value), it can be difficult to keep track of them. Sometimes you will want to clear all popups prior to initiating another UI action, like navigating the page or displaying a flyout.
Derive from above the flyout will render on the pop's content. so you could use GetOpenPopups
method to get it, if you want to hidden it just set the found Popup isopen property as false like the following.
private void DeleteColCancelClickHandler(object sender, RoutedEventArgs e)
{
var popups = VisualTreeHelper.GetOpenPopups(Window.Current);
foreach (var popup in popups)
{
if (popup is Popup)
{
popup.IsOpen = false;
}
}
}
And the other way is get flyout with Button Flyout Property
var flyout = DeleteColButton.Flyout;
flyout.Hide();
C++/WinRT
auto popups = VisualTreeHelper::GetOpenPopups(Window::Current());
for (int i = 0; i < popups.Size(); i++)
{
auto popup = popups.GetAt(i);
auto name = get_class_name(popup);
if (get_class_name(popup) == L"Windows.UI.Xaml.Controls.Primitives.Popup")
{
popup.IsOpen(false);
}
}