如何从 Button 引用父 Flyout? [C++/WinRT]

How to reference parent Flyout from Button? [C++/WinRT]

我有一个带有取消按钮的弹出窗口,我希望“取消”单击处理程序隐藏() 父弹出窗口。代码段(下方)是 ListBoxItem 的一部分,所以我无法通过 x:name="flyout_name".

引用弹出窗口

这意味着我需要遍历可视化树层次结构,但我无法访问父 Controls::Flyout 对象。

<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>

我可以从“取消”按钮转到弹出窗口中的顶级堆栈面板,但下一层既不是 Controls::Flyout 也不是 Controls::FlyoutPresenter。在“转义”顶级堆栈面板后,我可以调用 panel.GetParent() 11 次,并且那些 DependencyObjects 的 none 显示为 Flyout、FlyoutPresenter、StackPanel、ListBoxItem 或 ListBox。 Flyout 的视觉层次结构是否以某种方式与我通过 XAML 跟踪的层次结构断开连接?

我听说 Flyout 在可视化树中没有关联的 DependencyObject。真的是这样吗?如果我尝试自上而下,我将如何找到 ListBoxItem 的 DependencyObject?

我应该切换到对话框吗?


编辑:我试图从 ListBoxItem 访问按钮 ( Button().Flyout().Hide() ),但事实证明太困难了。

但是,使用 GetOpenPopups() 获取打开的弹出窗口列表 - 并将它们全部关闭 - 似乎有效。谢谢!

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.

为了解释这个,你需要先检查这个document

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.

从弹出窗口上方导出将呈现在流行音乐的内容上。所以你可以使用 GetOpenPopups 方法来获取它,如果你想隐藏它只需将找到的 Popup isopen 属性 设置为 false 如下所示。

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;
        }
    }

}

另一种方法是使用按钮 Flyout 属性

 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);
    }
}