-
Notifications
You must be signed in to change notification settings - Fork 59
Description
What would you like clarification on
I would appreciate if I would not always be required to lookup the Uno.Extensions/Samples/Playground/* Source Code then instead could get the same Information with eventual future learnings from the regular web Docs of Uno
For example:
uno.extensions/samples/Playground/Playground/App.xaml.cs
Lines 17 to 202 in 5235975
| protected async override void OnLaunched(LaunchActivatedEventArgs args) | |
| { | |
| MainWindow = new Window(); | |
| #if DEBUG | |
| MainWindow.EnableHotReload(); | |
| #endif | |
| var appBuilder = this.CreateBuilder(args) | |
| .ConfigureApp() | |
| .UseToolkitNavigation(); | |
| MainWindow = appBuilder.Window; | |
| var hostingOption = InitOption.Splash; | |
| switch (hostingOption) | |
| { | |
| case InitOption.AdHocHosting: | |
| // Ad-hoc hosting of Navigation on a UI element with Region.Attached set | |
| _host = appBuilder.Build(); | |
| // Create Frame and navigate to MainPage | |
| // MainPage has a ContentControl with Region.Attached set | |
| // which will host navigation | |
| var f = new Frame(); | |
| MainWindow.Content = f; | |
| await MainWindow.AttachServicesAsync(_host.Services); | |
| f.Navigate(typeof(MainPage)); | |
| await Task.Run(() => _host.StartAsync()); | |
| // With this way there's no way to await for navigation to finish | |
| // but it's useful if you want to attach navigation to a UI element | |
| // in an existing application | |
| break; | |
| case InitOption.NavigationRoot: | |
| // Explicitly create the navigation root to use | |
| _host = appBuilder.Build(); | |
| var root = new ContentControl | |
| { | |
| HorizontalAlignment = HorizontalAlignment.Stretch, | |
| VerticalAlignment = VerticalAlignment.Stretch, | |
| HorizontalContentAlignment = HorizontalAlignment.Stretch, | |
| VerticalContentAlignment = VerticalAlignment.Stretch | |
| }; | |
| MainWindow.Content = root; | |
| var services = await MainWindow.AttachServicesAsync(_host.Services); | |
| var startup = root.HostAsync(services, initialRoute: ""); | |
| await Task.Run(() => _host.StartAsync()); | |
| // Wait for startup task to complete which will be the end of the | |
| // first navigation | |
| await startup; | |
| break; | |
| case InitOption.InitializeNavigation: | |
| // InitializeNavigationAsync will create the navigation host (ContentControl), | |
| // will invoke the host builder (host is returned) and awaits both start up | |
| // tasks, as well as first navigation | |
| _host = await MainWindow.InitializeNavigationAsync(async () => appBuilder.Build(), | |
| // Option 1: This requires Shell to be the first RouteMap - best for perf as no reflection required | |
| // initialRoute: "" | |
| // Option 2: Specify route name | |
| // initialRoute: "Shell" | |
| // Option 3: Specify the view model. To avoid reflection, you can still define a routemap | |
| initialViewModel: typeof(ShellViewModel) | |
| ); | |
| break; | |
| case InitOption.Splash: | |
| // InitializeNavigationAsync (Navigation.Toolkit) uses a LoadingView as navigation host, | |
| // will invoke the host builder (host is returned) and awaits both start up | |
| // tasks, as well as first navigation. In this case the navigation host is an ExtendedSplashScreen | |
| // element, so will show the native splash screen until the first navigation is completed | |
| var appRoot = new AppRoot(); | |
| appRoot.SplashScreen.Initialize(MainWindow, args); | |
| MainWindow.Content = appRoot; | |
| _host = await MainWindow.InitializeNavigationAsync( | |
| async () => | |
| { | |
| // Uncomment to view splashscreen for longer | |
| // await Task.Delay(5000); | |
| return appBuilder.Build(); | |
| }, | |
| navigationRoot: appRoot.SplashScreen, | |
| // Option 1: This requires Shell to be the first RouteMap - best for perf as no reflection required | |
| // initialRoute: "" | |
| // Option 2: Specify route name | |
| // initialRoute: "Shell" | |
| // Option 3: Specify the view model. To avoid reflection, you can still define a routemap | |
| initialViewModel: typeof(HomeViewModel) | |
| ); | |
| break; | |
| case InitOption.AppBuilderShell: | |
| _host = await appBuilder.NavigateAsync<AppRoot>(); | |
| break; | |
| case InitOption.NoShellViewModel: | |
| // InitializeNavigationAsync with splash screen and async callback to determine where | |
| // initial navigation should go | |
| var appRootNoShell = new AppRoot(); | |
| appRootNoShell.SplashScreen.Initialize(MainWindow, args); | |
| MainWindow.Content = appRootNoShell; | |
| MainWindow.Activate(); | |
| _host = await MainWindow.InitializeNavigationAsync( | |
| async () => | |
| { | |
| return appBuilder.Build(); | |
| }, | |
| navigationRoot: appRootNoShell.SplashScreen, | |
| initialNavigate: async (sp, nav) => | |
| { | |
| // Uncomment to view splashscreen for longer | |
| await Task.Delay(5000); | |
| await nav.NavigateViewAsync<HomePage>(this); | |
| } | |
| ); | |
| break; | |
| } | |
| var notif = _host!.Services.GetRequiredService<IRouteNotifier>(); | |
| notif.RouteChanged += RouteUpdated; | |
| var logger = _host.Services.GetRequiredService<ILogger<App>>(); | |
| if (logger.IsEnabled(LogLevel.Trace)) logger.LogTraceMessage("LogLevel:Trace"); | |
| if (logger.IsEnabled(LogLevel.Debug)) logger.LogDebugMessage("LogLevel:Debug"); | |
| if (logger.IsEnabled(LogLevel.Information)) logger.LogInformationMessage("LogLevel:Information"); | |
| if (logger.IsEnabled(LogLevel.Warning)) logger.LogWarningMessage("LogLevel:Warning"); | |
| if (logger.IsEnabled(LogLevel.Error)) logger.LogErrorMessage("LogLevel:Error"); | |
| if (logger.IsEnabled(LogLevel.Critical)) logger.LogCriticalMessage("LogLevel:Critical"); | |
| } | |
| private enum InitOption | |
| { | |
| AdHocHosting, | |
| NavigationRoot, | |
| InitializeNavigation, | |
| Splash, | |
| NoShellViewModel, | |
| AppBuilderShell | |
| } | |
| public void RouteUpdated(object? sender, RouteChangedEventArgs? e) | |
| { | |
| try | |
| { | |
| var rootRegion = e?.Region.Root(); | |
| var route = rootRegion?.GetRoute(); | |
| if (route is null) | |
| { | |
| return; | |
| } | |
| #if !__WASM__ && !WINUI | |
| CoreApplication.MainView?.DispatcherQueue.TryEnqueue(() => | |
| { | |
| var appTitle = ApplicationView.GetForCurrentView(); | |
| appTitle.Title = "Commerce: " + (route + "").Replace("+", "/"); | |
| }); | |
| #endif | |
| } | |
| catch (Exception ex) | |
| { | |
| Console.WriteLine("Error: " + ex.Message); | |
| } | |
| } | |
| } |
Missing options currently:
- Different ways and to set up navigation using
Shell - Configuring SplashScreen without modifing it directly (?) line 103-109
- AppBuilder Shell (can anyone tell me what this is or for what it is usefull? -> you see, if we would have this in our docs, I wouldn't need to ask 👍 )
- No Shell VM ( maybe we can even remove the Shell with this if we want to?)
and I would also like to see a full collection of all available Route Registrations, instead of only selected ones:
uno.extensions/samples/Playground/Playground/AppHost.cs
Lines 75 to 192 in 9e1337c
| private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes) | |
| { | |
| var confirmDialog = new MessageDialogViewMap( | |
| Content: "Confirm this message?", | |
| Title: "Confirm?", | |
| DelayUserInput: true, | |
| DefaultButtonIndex: 1, | |
| Buttons: new DialogAction[] | |
| { | |
| new(Label: "Yeh!",Id:"Y"), | |
| new(Label: "Nah", Id:"N") | |
| } | |
| ); | |
| var localizedDialog = new LocalizableMessageDialogViewMap( | |
| Content: localizer => "[localized]Confirm this message?", | |
| Title: localizer => "[localized]Confirm?", | |
| DelayUserInput: true, | |
| DefaultButtonIndex: 1, | |
| Buttons: new LocalizableDialogAction[] | |
| { | |
| new(LabelProvider: localizer=> localizer!["Y"],Id:"Y"), | |
| new(LabelProvider: localizer=> localizer!["N"], Id:"N") | |
| } | |
| ); | |
| views.Register( | |
| // Option 1: Specify ShellView in order to customise the shell | |
| //new ViewMap<ShellView, ShellViewModel>(), | |
| // Option 2: Only specify the ShellViewModel - this will inject a FrameView where the subsequent pages will be shown | |
| new ViewMap(ViewModel: typeof(ShellViewModel)), | |
| new ViewMap<HomePage, HomeViewModel>(), | |
| new ViewMap<CodeBehindPage>(), | |
| new ViewMap<VMPage, VMViewModel>(), | |
| new ViewMap<XamlPage, XamlViewModel>(), | |
| new ViewMap<NavigationViewPage, NavigationViewViewModel>(), | |
| new ViewMap<NavContentPage, NavContentViewModel>(Data: new DataMap<NavWidget>()), | |
| new ViewMap<NavContentSecondPage>(), | |
| new ViewMap<TabBarPage>(), | |
| new ViewMap<ContentControlPage>(), | |
| new ViewMap<SecondPage, SecondViewModel>(Data: new DataMap<Widget>(), ResultData: typeof(Country)), | |
| new ViewMap<ThirdPage>(), | |
| new ViewMap<FourthPage, FourthViewModel>(), | |
| new ViewMap<FifthPage, FifthViewModel>(), | |
| new ViewMap<DialogsPage>(), | |
| new ViewMap<SimpleDialog, SimpleViewModel>(), | |
| new ViewMap<ComplexDialog>(), | |
| new ViewMap<ComplexDialogFirstPage>(), | |
| new ViewMap<ComplexDialogSecondPage>(), | |
| new ViewMap<PanelVisibilityPage>(), | |
| new ViewMap<VisualStatesPage>(), | |
| new ViewMap<AdHocPage, AdHocViewModel>(), | |
| new ViewMap<ListPage, ListViewModel>(), | |
| new ViewMap<ItemDetailsPage, ItemDetailsViewModel>(), | |
| new ViewMap<AuthTokenDialog, AuthTokenViewModel>(), | |
| new ViewMap<BasicFlyout, BasicViewModel>(), | |
| new ViewMap<ThemeSwitchPage, ThemeSwitchViewModel>(), | |
| confirmDialog, | |
| localizedDialog | |
| ); | |
| // RouteMap required for Shell if initialRoute or initialViewModel isn't specified when calling NavigationHost | |
| routes.Register( | |
| new RouteMap("", View: views.FindByViewModel<ShellViewModel>(), | |
| Nested: new[] | |
| { | |
| new RouteMap("Home",View: views.FindByView<HomePage>()), | |
| new RouteMap("CodeBehind",View: views.FindByView<CodeBehindPage>(), DependsOn: "Home"), | |
| new RouteMap("VM",View: views.FindByView<VMPage>(), DependsOn: "Home"), | |
| new RouteMap("Xaml",View: views.FindByView<XamlPage>(), DependsOn: "Home"), | |
| new RouteMap("NavigationView",View: views.FindByView<NavigationViewPage>(), DependsOn: "Home", | |
| Nested: new[] | |
| { | |
| new RouteMap("NavContent", View: views.FindByViewModel<NavContentViewModel>(), | |
| Nested: new[] | |
| { | |
| new RouteMap("NavContentTabs", IsDefault:true, | |
| Nested: new[] | |
| { | |
| new RouteMap("Tab1", IsDefault:true), | |
| new RouteMap("Tab2") | |
| }), | |
| }), | |
| new RouteMap("NavContentSecond", View: views.FindByView<NavContentSecondPage>(), DependsOn:"NavContent") | |
| }), | |
| new RouteMap("TabBar",View: views.FindByView<TabBarPage>(), DependsOn: "Home"), | |
| new RouteMap("ContentControl",View: views.FindByView<ContentControlPage>(), DependsOn: "Home"), | |
| new RouteMap("Second",View: views.FindByView<SecondPage>(), DependsOn: "Home"), | |
| new RouteMap("Third",View: views.FindByView<ThirdPage>()), | |
| new RouteMap("Fourth",View: views.FindByView<FourthPage>()), | |
| new RouteMap("Fifth",View: views.FindByView<FifthPage>(), DependsOn: "Third"), | |
| new RouteMap("Dialogs",View: views.FindByView<DialogsPage>(), | |
| Nested: new[] | |
| { | |
| new RouteMap("Simple",View: views.FindByView<SimpleDialog>()), | |
| new RouteMap("Complex",View: views.FindByView<ComplexDialog>(), | |
| Nested: new[] | |
| { | |
| new RouteMap("ComplexDialogFirst",View: views.FindByView<ComplexDialogFirstPage>()), | |
| new RouteMap("ComplexDialogSecond",View: views.FindByView<ComplexDialogSecondPage>(), DependsOn: "ComplexDialogFirst") | |
| }) | |
| }), | |
| new RouteMap("PanelVisibility",View: views.FindByView<PanelVisibilityPage>()), | |
| new RouteMap("VisualStates",View: views.FindByView<VisualStatesPage>()), | |
| new RouteMap("AdHoc",View: views.FindByViewModel<AdHocViewModel>(), | |
| Nested: new[] | |
| { | |
| new RouteMap("Auth", View: views.FindByView<AuthTokenDialog>()) | |
| }), | |
| new RouteMap("List",View: views.FindByViewModel<ListViewModel>()), | |
| new RouteMap("ItemDetails",View: views.FindByViewModel<ItemDetailsViewModel>()), | |
| new RouteMap("Confirm", View: confirmDialog), | |
| new RouteMap("LocalizedConfirm", View: localizedDialog) | |
| })); | |
| } |
Or this here:
uno.extensions/samples/Playground/Playground/App.xaml.cs
Lines 67 to 68 in 9e1337c
| var services = await MainWindow.AttachServicesAsync(_host.Services); | |
| var startup = root.HostAsync(services, initialRoute: ""); |
Might even be a partial answer to the usage of Xaml available Attached Property ServiceProvider?
- Navigation Reference is incomplete, please add the missing Propertys visible in xaml #2653
If you have more information about this, feel free to share!
Concern?
- Usage in industry
- Clarification of capabilities
- Getting started with Uno
- Developing with Uno
- Contributing to the Uno project
- Publishing your application
- Support
- Other (please specify):
For which Platform
- All Platforms 🌐
- Build tasks
Anything else we need to know?
@Jen-Uno some relevant to be documented informations to consider. We have this great sample directly here in the repo, so it even would greatly integrate with [code-csharp [](...)] markdown 🚀 just to find somebody willing to let us consumers know about them 👀 do you think this is possible to get in our future Uno docs?
Could also minimize the Agent-MCPs halucinating about Do's and Don't do's with the Shell 😅