From 84c05e5bb2a14a07ee17b9248b794254633a56f1 Mon Sep 17 00:00:00 2001 From: Artjom Graf Date: Mon, 13 May 2019 14:10:23 +0300 Subject: [PATCH] Add Universal Windows routing example --- samples/uwp/ReactiveUI.UwpRouting.sln | 51 +++++ samples/uwp/ReactiveUI.UwpRouting/App.xaml | 5 + samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs | 33 ++++ .../Assets/LockScreenLogo.scale-200.png | 3 + .../Assets/SplashScreen.scale-200.png | 3 + .../Assets/Square150x150Logo.scale-200.png | 3 + .../Assets/Square44x44Logo.scale-200.png | 3 + ...x44Logo.targetsize-24_altform-unplated.png | 3 + .../Assets/StoreLogo.png | 3 + .../Assets/Wide310x150Logo.scale-200.png | 3 + .../Package.appxmanifest | 49 +++++ .../Properties/AssemblyInfo.cs | 29 +++ .../Properties/Default.rd.xml | 31 +++ .../ReactiveUI.UwpRouting.csproj | 181 ++++++++++++++++++ .../ViewModels/FirstViewModel.cs | 15 ++ .../ViewModels/MainViewModel.cs | 39 ++++ .../Views/FirstView.xaml | 16 ++ .../Views/FirstView.xaml.cs | 30 +++ .../ReactiveUI.UwpRouting/Views/MainView.xaml | 19 ++ .../Views/MainView.xaml.cs | 31 +++ 20 files changed, 550 insertions(+) create mode 100644 samples/uwp/ReactiveUI.UwpRouting.sln create mode 100644 samples/uwp/ReactiveUI.UwpRouting/App.xaml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj create mode 100644 samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml create mode 100644 samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml.cs diff --git a/samples/uwp/ReactiveUI.UwpRouting.sln b/samples/uwp/ReactiveUI.UwpRouting.sln new file mode 100644 index 0000000000..f5624f7e8d --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting.sln @@ -0,0 +1,51 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.489 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveUI.UwpRouting", "ReactiveUI.UwpRouting\ReactiveUI.UwpRouting.csproj", "{702CB6D2-A9E0-40A4-A64D-BAACC63893A8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|ARM64 = Debug|ARM64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|ARM64 = Release|ARM64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM.ActiveCfg = Debug|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM.Build.0 = Debug|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM.Deploy.0 = Debug|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM64.Build.0 = Debug|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|ARM64.Deploy.0 = Debug|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x64.ActiveCfg = Debug|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x64.Build.0 = Debug|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x64.Deploy.0 = Debug|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x86.ActiveCfg = Debug|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x86.Build.0 = Debug|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Debug|x86.Deploy.0 = Debug|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM.ActiveCfg = Release|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM.Build.0 = Release|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM.Deploy.0 = Release|ARM + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM64.ActiveCfg = Release|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM64.Build.0 = Release|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|ARM64.Deploy.0 = Release|ARM64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x64.ActiveCfg = Release|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x64.Build.0 = Release|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x64.Deploy.0 = Release|x64 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x86.ActiveCfg = Release|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x86.Build.0 = Release|x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8}.Release|x86.Deploy.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7F4403AB-47C8-4125-8E65-DC8E07DBDA1E} + EndGlobalSection +EndGlobal diff --git a/samples/uwp/ReactiveUI.UwpRouting/App.xaml b/samples/uwp/ReactiveUI.UwpRouting/App.xaml new file mode 100644 index 0000000000..5d3b064472 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/App.xaml @@ -0,0 +1,5 @@ + + diff --git a/samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs b/samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs new file mode 100644 index 0000000000..3b952c8bf5 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/App.xaml.cs @@ -0,0 +1,33 @@ +using System; +using Windows.ApplicationModel.Activation; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Navigation; +using ReactiveUI.UwpRouting.Views; + +namespace ReactiveUI.UwpRouting +{ + public sealed partial class App : Application + { + public App() => InitializeComponent(); + + protected override void OnLaunched(LaunchActivatedEventArgs e) + { + if (!(Window.Current.Content is Frame rootFrame)) + { + rootFrame = new Frame(); + rootFrame.NavigationFailed += OnNavigationFailed; + Window.Current.Content = rootFrame; + } + + if (e.PrelaunchActivated != false) return; + if (rootFrame.Content == null) rootFrame.Navigate(typeof(MainView), e.Arguments); + Window.Current.Activate(); + } + + private static void OnNavigationFailed(object sender, NavigationFailedEventArgs e) + { + throw new Exception("Failed to load Page " + e.SourcePageType.FullName); + } + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png new file mode 100644 index 0000000000..8cf1cc0297 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/LockScreenLogo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a41a053b3fc3b0c109720ccd437a19725ae9163ea75990222a12b596b9c7ca76 +size 1430 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png new file mode 100644 index 0000000000..1ade290fb9 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/SplashScreen.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a3382b0b1b834e95b888f06d483dc2d78fa1b3855e0683d5cfbd5167be9731a6 +size 7700 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png new file mode 100644 index 0000000000..f269619be8 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square150x150Logo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f3cb5738e8f05544445f79996a313f8b47dee22dbc9c7be859d2707710f0c73 +size 2937 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png new file mode 100644 index 0000000000..818d96d80a --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:594492a25070951d7462c091d9f899a66f55ba992bb9b05d98d50f67cdfb2abe +size 1647 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png new file mode 100644 index 0000000000..8c010282f4 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Square44x44Logo.targetsize-24_altform-unplated.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:48cf9c22156a0b3d77982641f972785e7861a7257f7bcf155be7d5a12e1aa3d8 +size 1255 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png new file mode 100644 index 0000000000..679f7d7461 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/StoreLogo.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ae95e99a96251abaf8de15c9cdaddb8cefb1b8b320b10a4f1f4e1dc3c25c1b1a +size 1451 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png b/samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png new file mode 100644 index 0000000000..7578982624 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Assets/Wide310x150Logo.scale-200.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b5b7754832c08e58faacfe64ea4b9f8b59b52a658e4eea4aab3790cfb89faa03 +size 3204 diff --git a/samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest b/samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest new file mode 100644 index 0000000000..eb37fd2af9 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Package.appxmanifest @@ -0,0 +1,49 @@ + + + + + + + + + + ReactiveUI.UwpRouting + prizr + Assets\StoreLogo.png + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs b/samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..73eef03c56 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("ReactiveUI.UwpRouting")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ReactiveUI.UwpRouting")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml b/samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml new file mode 100644 index 0000000000..af00722cdf --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Properties/Default.rd.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj b/samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj new file mode 100644 index 0000000000..eb2cc216d5 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/ReactiveUI.UwpRouting.csproj @@ -0,0 +1,181 @@ + + + + + Debug + x86 + {702CB6D2-A9E0-40A4-A64D-BAACC63893A8} + AppContainerExe + Properties + ReactiveUI.UwpRouting + ReactiveUI.UwpRouting + en-US + UAP + 10.0.17763.0 + 10.0.17763.0 + 14 + 512 + {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + ReactiveUI.UwpRouting_TemporaryKey.pfx + + + true + bin\x86\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x86 + false + prompt + true + + + bin\x86\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x86 + false + prompt + true + true + + + true + bin\ARM\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM + false + prompt + true + + + bin\ARM\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM + false + prompt + true + true + + + true + bin\ARM64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + ARM64 + false + prompt + true + true + + + bin\ARM64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + ARM64 + false + prompt + true + true + + + true + bin\x64\Debug\ + DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP + ;2008 + full + x64 + false + prompt + true + + + bin\x64\Release\ + TRACE;NETFX_CORE;WINDOWS_UWP + true + ;2008 + pdbonly + x64 + false + prompt + true + true + + + PackageReference + + + + App.xaml + + + + + + FirstView.xaml + + + MainView.xaml + + + + + Designer + + + + + + + + + + + + + + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + MSBuild:Compile + Designer + + + + + 6.2.8 + + + 9.15.1 + + + + 14.0 + + + + \ No newline at end of file diff --git a/samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs new file mode 100644 index 0000000000..f0cb835f3f --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/FirstViewModel.cs @@ -0,0 +1,15 @@ +using System; + +namespace ReactiveUI.UwpRouting.ViewModels +{ + public class FirstViewModel : ReactiveObject, IRoutableViewModel + { + // Reference to IScreen that owns the routable view model. + public IScreen HostScreen { get; } + + // Unique identifier for the routable view model. + public string UrlPathSegment { get; } = Guid.NewGuid().ToString().Substring(0, 5); + + public FirstViewModel(IScreen screen) => HostScreen = screen; + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs new file mode 100644 index 0000000000..62e3ffabcd --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/ViewModels/MainViewModel.cs @@ -0,0 +1,39 @@ +using System.Reactive; +using ReactiveUI.UwpRouting.Views; +using Splat; + +namespace ReactiveUI.UwpRouting.ViewModels +{ + public class MainViewModel : ReactiveObject, IScreen + { + // The Router associated with this Screen. + // Required by the IScreen interface. + public RoutingState Router { get; } = new RoutingState(); + + // The command that navigates a user to first view model. + public ReactiveCommand GoNext { get; } + + // The command that navigates a user back. + public ReactiveCommand GoBack => Router.NavigateBack; + + public MainViewModel() + { + // Router uses Splat.Locator to resolve views for + // view models, so we need to register our views + // using Locator.CurrentMutable.Register* methods. + // + Locator.CurrentMutable.Register(() => new FirstView(), typeof(IViewFor)); + + // Manage the routing state. Use the Router.Navigate.Execute + // command to navigate to different view models. + // + // Note, that the Navigate.Execute method accepts an instance + // of a view model, this allows you to pass parameters to + // your view models, or to reuse existing view models. + // + GoNext = ReactiveCommand.CreateFromObservable( + () => Router.Navigate.Execute(new FirstViewModel(this)) + ); + } + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml new file mode 100644 index 0000000000..53fecbb525 --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs new file mode 100644 index 0000000000..dc1470a19f --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Views/FirstView.xaml.cs @@ -0,0 +1,30 @@ +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using ReactiveUI.UwpRouting.ViewModels; + +namespace ReactiveUI.UwpRouting.Views +{ + public sealed partial class FirstView : UserControl, IViewFor + { + public static readonly DependencyProperty ViewModelProperty = DependencyProperty + .Register(nameof(ViewModel), typeof(FirstViewModel), typeof(FirstView), null); + + public FirstView() + { + InitializeComponent(); + this.WhenActivated(disposables => { }); + } + + public FirstViewModel ViewModel + { + get => (FirstViewModel)GetValue(ViewModelProperty); + set => SetValue(ViewModelProperty, value); + } + + object IViewFor.ViewModel + { + get => ViewModel; + set => ViewModel = (FirstViewModel)value; + } + } +} diff --git a/samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml b/samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml new file mode 100644 index 0000000000..7fa82a804f --- /dev/null +++ b/samples/uwp/ReactiveUI.UwpRouting/Views/MainView.xaml @@ -0,0 +1,19 @@ + + + + + + + + +