Используя несколько представлений с Template10, не всегда показывая главную страницу?
Я новичок в T10 и пытаюсь научиться этому. Это продолжение шаблона 10 Несколько окон
В "обычном" (то есть не в Template10) приложении UWP я научился делать что-то вроде этого (в качестве краткого примера) для поддержки нескольких представлений:
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;
}
Теперь: как мне это сделать с Template10? Я посмотрел пример https://github.com/Windows-XAML/Template10/wiki/Multiple-Views но не могу понять. Более конкретно, я хочу перейти на определенную страницу при использовании активации протокола (с использованием шаблона Hamburger). Вот что я дошел до сих пор:
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
}
}
Это работает за исключением того, что главная страница также отображается (вместе с DetailPage) с OpenAsync. При использовании "обычного" подхода UWP, описанного выше, у меня нет проблемы. Как я могу заставить это работать, как я хотел бы? Я уверен, что это что-то простое.
Мне пока нравится T10 - спасибо Джерри и команде за вклад.
РЕДАКТИРОВАТЬ Подробнее
На основании приведенных ниже предложений я изменил код (в App.xaml.cs) на:
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));
}
}
а также:
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(),
};
}
Теперь у меня есть пустая форма, которая также отображается при использовании активации протокола (и больше не форма Shell, как отмечает Sunteen), потому что (я думаю) строки помечены как "НЕПРАВИЛЬНО" выше. Насколько я понимаю, CreateRootElement необходимо выполнить, но когда приложение активируется по протоколу, у меня нет / не хочу отображать корневой фрейм; но CreateRootElement должен что-то вернуть. Как вы можете видеть из моего примера, это не совсем как пример MultipleViews, потому что в этом примере всегда есть корневой фрейм. Примечание: Кроме того, я думаю, что с T10 я не должен / не могу использовать прямую навигацию, как предлагает Sunteen: навигация должна быть обработана T10.
Благодарю.
2 ответа
Это работает за исключением того, что главная страница также отображается (вместе с DetailPage) с OpenAsync
Я думаю, что вы имеете в виду Shell.xaml
страница также отображается. Это потому, что в настоящее время NavigationService
принадлежит к кадру, который без Shell
страница внутри, Shell
страница уже создана до навигации CreateRootElement
метод.
Я хочу перейти на определенную страницу при использовании активации протокола (с использованием шаблона Hamburger)
Чтобы удовлетворить ваши требования, я бы рекомендовал вам не нарушать структуру навигации в вашем проекте, а создать новый фрейм для специального сценария, запускаемого по протоколу. Например:
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
}
}
В новом коде уже есть полный пример, который вскоре будет выпущен. Его под веткой источника v 1.1.3p
https://github.com/Windows-XAML/Template10/tree/version_1.1.13p/Samples/MultipleViews/ViewModels
последний выпуск V 1.1.2_vs2017, который является обновлением шаблона для VS2017, также имеет тот же пример, который выложенный код более или менее такой же под обложками с некоторыми изменениями, чтобы заставить его работать должным образом с T10