【问题标题】:How to reference parent Flyout from Button? [C++/WinRT]如何从 Button 引用父 Flyout? [C++/WinRT]
【发布时间】:2021-06-20 09:54:09
【问题描述】:

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

这意味着我需要遍历 Visual Tree Hierarchy,但我无法访问父 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 次,并且这些 DependencyObject 都没有显示为 Flyout、FlyoutPresenter、StackPanel、ListBoxItem 或 ListBox。 Flyout 的视觉层次结构是否与我通过 XAML 跟踪的层次结构脱节?

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

我应该切换到对话框吗?


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

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

【问题讨论】:

    标签: c++-winrt


    【解决方案1】:

    我可以在弹出窗口中从“取消”按钮转到顶层堆栈面板,但下一层既不是 Controls::Flyout 也不是 Controls::FlyoutPresenter。

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

    从根视觉开始的常规 XAML 视觉树中不存在弹出窗口,尽管它们与应用主窗口相关联。除非您的应用程序维护您创建的所有 Popup 元素的列表以及状态(IsOpen 值),否则很难跟踪它们。有时您需要在启动另一个 UI 操作(例如导航页面或显示浮出控件)之前清除所有弹出窗口。

    从上方派生的浮出控件将在弹出的内容上呈现。所以你可以使用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;
            }
        }
    
    }
    

    另一种方法是使用 Button 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);
        }
    }
    

    【讨论】:

    • 问题标记为 C++/WinRT。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    相关资源
    最近更新 更多