【问题标题】:UWP Grid.ContextFlyout not openingUWP Grid.ContextFlyout 未打开
【发布时间】:2019-03-16 05:47:55
【问题描述】:

在我的 UWP 应用程序中,我的主窗口中有一个列表视图,我有一个辅助窗口。我的列表视图中的每个列表视图项都是Grid,我为网格设置了Grid.ContextFlyout。 ContextFlyout 包含一个 MenuFlyout 和 4 个 MenuFlyoutItem

我打开我的应用程序,在主窗口列表视图中,我右键单击一个项目。我看到 ContextFlyout 打开,EventHandler<object> Opened 被触发。

现在,我打开应用程序的辅助窗口并关闭主窗口。我再次通过从开始菜单打开我的应用程序来打开我的应用程序的主窗口。

现在,如果我右键单击之前单击的列表视图中的同一项目,我可以看到 EventHandler<object> Opened 被触发,但上下文弹出窗口未在 UI 中打开。

此问题仅在上述情况下发生(1.打开应用程序,2.右键单击项目,3.打开辅助窗口,4.关闭主窗口,5.从开始再次打开应用程序的主窗口菜单,6.右键单击该项目)

下面是我的网格

<Grid
    Name="RootGrid">
    <Grid.ContextFlyout>
        <MenuFlyout
            x:Name="OptionsFlyout"
            Opening="Flyout_Opening" 
            Opened="Flyout_Opened"
            Closed="Flyout_Closed">
            <MenuFlyoutItem Name="Item1"/>
            <MenuFlyoutItem Name="Item2"/>
            <MenuFlyoutItem Name="Item3"/>
            <MenuFlyoutItem Name="Item4"/>
        </MenuFlyout>
    </Grid.ContextFlyout>
    <TextBlock Text="MyGridItem"/>
</Grid>

在我的App.xaml.cs 中,我在OnLaunched 方法中使用下面的代码来恢复我的主窗口

protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
    Window.Current.Dispatcher.RunOnUIThread(async () =>
    {
      tryShow = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(ApplicationView.GetApplicationViewIdForWindow(CoreApplication.GetCurrentView().CoreWindow), ViewSizePreference.Default, e.CurrentlyShownApplicationViewId, ViewSizePreference.Default);
    });
}

在打开/恢复之前关闭的主窗口时,我是否遗漏了任何内容?或者有什么办法可以解决这个问题?

以下是我为重现此问题而创建的示例应用程序的 github 链接。 UWP Grid Context Menu

【问题讨论】:

  • @XavierXie-MSFT 我已经使用示例应用程序的 github 链接编辑了我的问题,以重现此问题。

标签: c# xaml uwp


【解决方案1】:

此问题仅在上述情况下发生(1.打开应用程序,2.右键单击项目,3.打开辅助窗口,4.关闭主窗口,5.从开始再次打开应用程序的主窗口菜单,6.右键单击该项目)

我可以重现这个问题。我已经向相关团队报告了。您也可以在我们的反馈中心提交。

这里有一个解决方法。您可以使用 FlyoutBase.AttachedFlyout 而不是 'ContextFlyout'。只需注册 Grid 的RightTapped 事件并添加如下代码即可:

<Grid Name="RootGrid" Height="50" Width="200" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Green" RightTapped="RootGrid_RightTapped">
       <FlyoutBase.AttachedFlyout>
            <MenuFlyout
        x:Name="OptionsFlyout"
            Opening="MenuFlyout_Opening" 
            Opened="FolderOptionsFlyout_Opened"
            Closed="FolderOptionsFlyout_Closed">
                        <MenuFlyoutItem Name="Item1" Text="Item1"/>
                        <MenuFlyoutItem Name="Item2" Text="Item2"/>
                        <MenuFlyoutItem Name="Item3" Text="Item3"/>
                        <MenuFlyoutItem Name="Item4" Text="Item4"/>
             </MenuFlyout>
       </FlyoutBase.AttachedFlyout>
       <TextBlock Text="{x:Bind}" Height="150" Width="100"/>
</Grid>
private void RootGrid_RightTapped(System.Object sender, RightTappedRoutedEventArgs e)
{
    var fe = sender as FrameworkElement;
    var menu = Flyout.GetAttachedFlyout(fe);
    menu.ShowAt(fe);
}

【讨论】:

    【解决方案2】:

    根据文档关闭主窗口应该只是隐藏它。
    来自Show multiple views for an app

    “如果辅助视图打开,则可以隐藏主视图的窗口 - 例如,通过单击窗口标题栏中的关闭 (x) 按钮 - 但其线程仍处于活动状态。”

    从 1703 开始​​,您可以让主窗口处理关闭请求事件。关闭后,代码可以在隐藏主窗口的同时切换到辅助窗口。然后通过将 Handled 属性设置为 true 来告诉系统您已经自己处理了关闭。

    在 appxmanifest 中添加 confirmAppClose 功能。

    <Capabilities>
         <Capability Name="internetClient" />
         <rescap:Capability Name="confirmAppClose"/> 
    </Capabilities>
    

    现在处理 CloseRequested 事件。代码如下所示:

        private int MainViewId;
        private int SecondViewId;
    
        public MainPage()
        {
            this.InitializeComponent();
            SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += MainPage_CloseRequested;
        }
    
        private async void MainPage_CloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
        {   
            // Switch to Secondary window, Hide main window                          
            await ApplicationViewSwitcher.SwitchAsync(
                    SecondViewId,
                    MainViewId,
                    ApplicationViewSwitchingOptions.ConsolidateViews);
    
            // The close was handled, don't do anything else
            e.Handled = true;
        }
    
        private async void Button_Tapped(object sender, TappedRoutedEventArgs e)
        {
            MainViewId = ApplicationView.GetForCurrentView().Id;
            var newCoreApplicationView = CoreApplication.CreateNewView();             
    
            await newCoreApplicationView.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                SecondViewId = ApplicationView.GetForCurrentView().Id;
    
                Window SecondWindow = Window.Current;
                var frame = new Frame();
                frame.Navigate(typeof(Assets.SecondWindow));
                SecondWindow.Content = frame;
                SecondWindow.Activate();
            });
    
            await ApplicationViewSwitcher.TryShowAsStandaloneAsync(SecondViewId, ViewSizePreference.Default);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多