Flyout的“轻量级解除”导致需要两次点击才能打开下一个Flyout

3

我有两个按钮,点击后显示弹出窗口。我像XAML UI基础示例中所演示的那样显示它们:

private void ButtonTapped(object sender, TappedRoutedEventArgs e)
{
    FrameworkElement element = sender as FrameworkElement;
    if (element != null)
    {               
        FlyoutBase.ShowAttachedFlyout(element);
    }
}

我的问题是,如果按钮1的弹出菜单已经打开,下一次点击屏幕会关闭弹出菜单。这很好,但如果下一次点击发生在按钮2上,我希望按钮的点击事件被触发并打开它的弹出菜单。相反,该按钮根本没有注册点击事件,并关闭了按钮1的弹出菜单。
这导致需要点击两次-一次用于关闭按钮1的弹出菜单,第二次用于显示按钮2的弹出菜单。
换句话说:
当前流程:
1. 点击按钮1 2. 按钮1的弹出菜单被打开 3. 点击按钮2 4. 按钮1的弹出菜单关闭,(按钮2或页面都没有注册点击事件) 5. 再次点击按钮2 6. 现在按钮2的弹出菜单被打开
我想要的是:
1. 点击按钮1 2. 按钮1的弹出菜单被打开 3. 点击按钮2 4. 按钮1的弹出菜单关闭,按钮2的弹出菜单打开。
如何做到这一点?我尝试拦截页面的Tapped事件,但当弹出菜单打开时,它似乎会拦截Tapped事件,以便用于弹出菜单的轻松解除。
覆盖Flyout的样式或FlyoutPresenterStyle能帮我吗?或者以更MVVM-ish的方式打开弹出菜单,这将允许我更精细地控制如何打开/关闭弹出菜单?
我不确定如何解决这个问题!

你找到解决方案了吗?我也在使用MenuFlyout作为上下文菜单时遇到了同样的问题。 - Martin Suchan
没有,目前还没有解决方案。我可能会尝试用弹出窗口替换Flyout,并查看是否可以更精细地控制其关闭。 - flyte
1个回答

3

我在微软文档中找到了以下内容:

当点击时,此手势通常会被吸收,而不会传递给底部的UI。例如,如果打开的flyout后面有一个可见的按钮,用户的第一次点击将关闭flyout,但不会激活此按钮。按下该按钮需要第二次点击。

您可以通过将按钮指定为flyout的输入穿透元素来更改此行为。由于上述轻量级解除操作,flyout将关闭,并将触摸事件传递给其指定的OverlayInputPassThroughElement。考虑采用这种行为以加快功能类似的项目上的用户交互。如果您的应用程序具有收藏夹集合,并且集合中的每个项目都包括附加的flyout,则可以合理地预期用户可能希望快速连续地与多个flyout交互。

[!NOTE] 谨慎指定覆盖层输入穿透元素,因为这可能会导致破坏性的操作。用户已经习惯了离散的轻量级解除操作,这些操作不会激活主要UI。关闭、删除或类似的破坏性按钮不应在轻量级解除时激活,以避免意外和破坏性行为。 在下面的示例中,FavoritesBar内的所有三个按钮将在第一次点击时被激活。

<Page>
<Page.Resources>
    <Flyout x:Name="TravelFlyout" x:Key="TravelFlyout"
            OverlayInputPassThroughElement="{x:Bind FavoritesBar}">
        <StackPanel>
            <HyperlinkButton Content="Washington Trails Association"/>
            <HyperlinkButton Content="Washington Cascades - Go Northwest! A Travel Guide"/>  
        </StackPanel>
    </Flyout>
</Page.Resources>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <StackPanel x:Name="FavoritesBar" Orientation="Horizontal">
        <HyperlinkButton x:Name="PageLinkBtn">Bing</HyperlinkButton>  
        <Button x:Name="Folder1" Content="Travel" Flyout="{StaticResource TravelFlyout}"/>
        <Button x:Name="Folder2" Content="Entertainment" Click="Folder2_Click"/>
    </StackPanel>
    <ScrollViewer Grid.Row="1">
        <WebView x:Name="WebContent"/>
    </ScrollViewer>
</Grid>

private void Folder2_Click(object sender, RoutedEventArgs e){
 Flyout flyout = new Flyout();
 flyout.OverlayInputPassThroughElement = FavoritesBar;

 flyout.ShowAt(sender as FrameworkElement);}

文档链接:https://learn.microsoft.com/zh-cn/windows/uwp/design/controls-and-patterns/dialogs-and-flyouts/flyouts - Michael Hawker - MSFT

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