刷新 NavigationView 时导航到特定的 ContentFrame

Navigating to specific ContentFrame when refreshing NavigationView

我有一个应用程序使用 NavigationView 作为 UI 控件。

现在我有一个 SettingsPage,我可以在其中将我的 UI 语言更改为德语和英语。

我用这段代码更改语言:

public static void German()
    {
        Log.Logger.Information("Language = German")

        ApplicationLanguages.PrimaryLanguageOverride = "de-DE";
        DataCollection.Current.LanguageChangedEvent.LanguageChanged();
    }

最后一行调用 EventHandler,后者又在 NavigationView 所在的 MainPage.xaml.cs 上调用以下事件。

public void ChangedLanguage(object source, EventHandlerBase e)
    {
        if (e.GetStatus())
        {

            Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
            Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();

            Frame.Navigate(this.GetType());

            ContentFrame.Navigate(typeof(SettingsPage));
        }
    }

可以看出,我只想 return 用户在更改语言后转到 SettingsPage。 但我总是 return 回到我在启动应用程序时使用的初始 HomePage

我使用的NavigationView代码来源于微软官方提供的NavigationView sample

有没有办法做到这一点?我能想到的唯一可能的事情是在第一页加载后设置一个标志,然后始终检查是否设置了该标志。但后来我遇到了问题,我仍然只能降落在 SettingsPage,因为我必须将其设为 else 标志检查的目的地。

如果可能的话,我真的很感激更动态的方式:/

您好, 丹尼尔

NavigationView sample 只是一个简单的代码示例,供您参考。您需要根据您的要求进行一些更改。

I just want to return the user to the SettingsPage after changing the language. But I always return back to the initial HomePage that I use when starting the app.

我已经使用文档中的代码制作了代码示例进行测试。有两个地方会引起你的疑问。

首先,在NavView_Loaded事件处理程序中,它总是将主页设置为所选项目。但是当您更改语言时,您会重新导航到 'MainPage' 并使 'ContentFrame' 导航到 'SettingsPage'。这时候,On_Navigated事件处理程序会首先被调用。然后,将调用 NavView_Loaded 事件处理程序。这就是为什么您的应用总是 return 到主页的原因。

其次,如果已设置 NavigationView 的 SelectedItem,则事件。但是 NavigationView 的 ItemInvoked event will not be fired. So, what you see actually is not home page, it's a blank Frame control. You could use SelectionChanged event 而不是 ItemInvoked 事件。当您为 NavigationView 的 SelectedItem 设置新值时,将触发 SelectionChanged 事件。请参阅以下示例:

private void NavView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
    if (args.IsSettingsSelected)
    {
        ContentFrame.Navigate(typeof(SettingsPage));
    }
    else
    {
        NavView_Navigate(args.SelectedItem as NavigationViewItem);
    }
}

那么,让我们回到你原来的问题:

I can imagine is to set a flag after the first page loading and then always check if that flag is set. But then I have the problem that I still could only land at the SettingsPage because I would have to make it the else destination for the flag-check.

在我看来,flag 不会影响你做其他事情。您完全可以定义多个标志。请参阅我的以下代码片段以供参考:

public static void German()
{
    Log.Logger.Information("Language = German")
    ApplicationLanguages.PrimaryLanguageOverride = "de-DE";
    ApplicationData.Current.LocalSettings.Values["IsSwitchingLanguage"] = true;
    DataCollection.Current.LanguageChangedEvent.LanguageChanged();
}

在你的 MainPage.xaml.cs:

public void ChangedLanguage(object source, EventHandlerBase e)
{
        if (e.GetStatus())
        {
            Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();
            Windows.ApplicationModel.Resources.Core.ResourceContext.GetForViewIndependentUse().Reset();
            Frame.Navigate(this.GetType());

        }
}

NavView_Loaded 事件处理程序中,我做了一些更改:

private void NavView_Loaded(object sender, RoutedEventArgs e)
{
        ...... 
        foreach (NavigationViewItemBase item in NavView.MenuItems)
        {
            var IsSwitchingLanguage = ApplicationData.Current.LocalSettings.Values["IsSwitchingLanguage"];
            if (IsSwitchingLanguage != null)
            {
                if ((bool)IsSwitchingLanguage)
                {
                    NavView.SelectedItem = NavView.SettingsItem as NavigationViewItem;
                    ApplicationData.Current.LocalSettings.Values["IsSwitchingLanguage"] = false;
                    break;
                }

            }
            if (item is NavigationViewItem && item.Tag.ToString() == "home")
            {
                NavView.SelectedItem = item;
                break;
            }
        }

        ......
}