问题
I am new to T10 and trying to learn it. This is a follow-up to Template 10 Multiple Windows
In 'regular' (meaning non-Template10) UWP app I've learned to do something like this (as a short example) in order to support multiple views:
public App() { InitializeComponent(); Suspending += OnSuspending; }
readonly List<CoreDispatcher> _dispatchers = new List<CoreDispatcher>();
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
Frame rootFrame = Window.Current.Content as Frame;
if (rootFrame == null)
{
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
Window.Current.Content = rootFrame;
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
Window.Current.Activate();
_dispatchers.Add(CoreWindow.GetForCurrentThread().Dispatcher);
}
else
{
var view = CoreApplication.CreateNewView();
int windowId = 0;
await view.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
windowId = ApplicationView.GetApplicationViewIdForWindow(CoreWindow.GetForCurrentThread());
var frame = new Frame();
frame.Navigate(typeof(MainPage), null);
Window.Current.Content = frame;
Window.Current.Activate();
ApplicationView.GetForCurrentView().Consolidated += View_Consolidated;
});
await _dispatchers[_dispatchers.Count - 1].RunAsync
(
CoreDispatcherPriority.Normal, async () => { var _ = await ApplicationViewSwitcher.TryShowAsStandaloneAsync(windowId); }
);
_dispatchers.Add(view.Dispatcher);
}
}
private void View_Consolidated(ApplicationView sender, ApplicationViewConsolidatedEventArgs args)
{
_dispatchers.Remove(CoreWindow.GetForCurrentThread().Dispatcher);
ApplicationView.GetForCurrentView().Consolidated -= View_Consolidated;
}
Now: how do I do this with Template10? I've looked at the https://github.com/Windows-XAML/Template10/wiki/Multiple-Views sample but can't figure it out. More specifically, I want to go to a specific page when using protocol activation (using Hamburger template). Here's what I've come up so far :
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
var protocolArgs = args as ProtocolActivatedEventArgs;
if (protocolArgs != null && protocolArgs.Uri != null)
{
await NavigationService.OpenAsync(typeof(Views.DetailPage)); // protocol activation
}
else
{
await NavigationService.NavigateAsync(typeof(Views.MainPage)); // regular activation
}
}
This works EXCEPT that the Main page is also displayed (along with the DetailPage) with the OpenAsync. Using the 'regular' UWP approach described above I do not have the issue. How can I get this to work as I'd like? I'm sure this is something simple.
I like T10 so far - thanks Jerry and team for the contribution.
EDIT More Details
Based on suggestions below, I changed the code (in App.xaml.cs) to:
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
var protocolArgs = args as ProtocolActivatedEventArgs;
if (protocolArgs != null)
{
var pageName = protocolArgs.Uri.AbsolutePath;
if (!string.IsNullOrEmpty(pageName))
{
string pageId = protocolArgs.Uri.LocalPath;
var pageQuery = protocolArgs.Uri.Query;
// Here would navigate to the page specified by "pageId"... as an example:
if (pageId == "foo")
await NavigationService.OpenAsync(typeof(Views.FooPage), null, pageQuery);
else if (pageId == "bar")
await NavigationService.OpenAsync(typeof(Views.BarPage), null, pageQuery);
else
await NavigationService.NavigateAsync(typeof(Views.MainPage));
}
}
else
{
await NavigationService.NavigateAsync(typeof(Views.MainPage));
}
}
and:
public override UIElement CreateRootElement(IActivatedEventArgs args)
{
var service = NavigationServiceFactory(BackButton.Attach, ExistingContent.Exclude);
var protocolArgs = args as ProtocolActivatedEventArgs;
var pageName = protocolArgs?.Uri.AbsolutePath;
if (!string.IsNullOrEmpty(pageName))
{
return new Frame(); <<---------- WRONG?
}
return new ModalDialog
{
DisableBackButtonWhenModal = true,
Content = new Views.Shell(service),
ModalContent = new Views.Busy(),
};
}
Now, I have a blank form that is also displayed when using protocol activation (and no longer the Shell form as noted by Sunteen), because (I think) of the line flagged 'WRONG' above. My understanding is that CreateRootElement needs to be executed, but when the app is activated by protocol I don't have / don't want a root frame to display; but CreateRootElement must return something. As you can see by my example, it's not exactly as the MultipleViews sample because that example always have a root frame. Note: Furthermore, I think that with T10 I should not/cannot use direct navigation as suggested by Sunteen: the navigation must all be handled by T10.
Thanks.
回答1:
This works EXCEPT that the Main page is also displayed (along with the DetailPage) with the OpenAsync
I think you mean the Shell.xaml
page is also displayed. This is because the currently NavigationService is belonged to the frame that without Shell
page inside, the Shell
page already created before navigation by CreateRootElement
method.
I want to go to a specific page when using protocol activation (using Hamburger template)
To meet your requirements,I'd recommend you not to break the navigation structure in your project, but create a new frame for the special scenario that launched by protocol. For example:
public override async Task OnStartAsync(StartKind startKind, IActivatedEventArgs args)
{
// TODO: add your long-running task here
var protocolArgs = args as ProtocolActivatedEventArgs;
if (protocolArgs != null && protocolArgs.Uri != null)
{
Frame newframe = new Frame();
newframe.Navigate(typeof(Views.DetailPage));
Window.Current.Content = newframe; // protocol activation
}
else
{
await NavigationService.NavigateAsync(typeof(Views.MainPage)); // regular activation
}
}
回答2:
There is a complete sample already in the newer code that is being pushed out shortly. Its under source branch v 1.1.3p
https://github.com/Windows-XAML/Template10/tree/version_1.1.13p/Samples/MultipleViews/ViewModels
the most recent release V 1.1.2_vs2017 which is the template update for VS2017 also has the same sample, which the code that you posted is more or less the same under the covers with some tweaks to make it work proper with T10
来源:https://stackoverflow.com/questions/45340770/using-multiple-views-with-template10-without-always-showing-the-main-page