Skip to content

Commit

Permalink
feat: Using data as viewmodel for navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
nickrandolph committed May 30, 2022
1 parent a506c6b commit 7ade063
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 15 deletions.
Expand Up @@ -133,6 +133,8 @@ private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes)
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>(),
confirmDialog,
Expand Down Expand Up @@ -188,6 +190,8 @@ private static void RegisterRoutes(IViewRegistry views, IRouteRegistry routes)
{
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)
}));
Expand Down
Expand Up @@ -35,6 +35,8 @@
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\FifthViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\FourthViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\HomeViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ItemDetailsViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\ListViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\NavContentViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\NavigationViewViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModels\SecondViewModel.cs" />
Expand Down Expand Up @@ -85,8 +87,11 @@
<Compile Include="$(MSBuildThisFileDirectory)Views\HomePage.xaml.cs">
<DependentUpon>HomePage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Views\ListViewPage.xaml.cs">
<DependentUpon>ListViewPage.xaml</DependentUpon>
<Compile Include="$(MSBuildThisFileDirectory)Views\ItemDetailsPage.xaml.cs">
<DependentUpon>ItemDetailsPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Views\ListPage.xaml.cs">
<DependentUpon>ListPage.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Views\MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
Expand Down Expand Up @@ -186,7 +191,11 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Views\ListViewPage.xaml">
<Page Include="$(MSBuildThisFileDirectory)Views\ItemDetailsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Views\ListPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
Expand Down
Expand Up @@ -10,5 +10,12 @@
<PropertyGroup />
<Import Project="Playground.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />

<ItemGroup>
<_Globbed_Compile Remove="ViewModels\ItemDetailsViewModel.cs" />
<_Globbed_Compile Remove="ViewModels\ListViewModel.cs" />
<_Globbed_Compile Remove="Views\ItemDetailsPage.xaml.cs" />
</ItemGroup>
<ItemGroup>
<_Globbled_Page Remove="Views\ItemDetailsPage.xaml" />
</ItemGroup>
</Project>
@@ -0,0 +1,5 @@
namespace Playground.ViewModels;

public record ItemDetailsViewModel(Widget Widget)
{
}
@@ -0,0 +1,18 @@
namespace Playground.ViewModels;

public class ListViewModel
{
public ItemDetailsViewModel[] Items { get; } = new ItemDetailsViewModel[]
{
new ItemDetailsViewModel(new Widget("Fred",49.0)),
new ItemDetailsViewModel(new Widget("Jane",34.2)),
new ItemDetailsViewModel(new Widget("Bob",46.3)),
new ItemDetailsViewModel(new Widget("Frank",55.2)),
new ItemDetailsViewModel(new Widget("Matt",45.7)),
new ItemDetailsViewModel(new Widget("Shane",99.3)),
new ItemDetailsViewModel(new Widget("Helen",23.7)),
new ItemDetailsViewModel(new Widget("Jo",34.5)),
new ItemDetailsViewModel(new Widget("Mike",23.3))
};

}
@@ -1,5 +1,5 @@
<Page
x:Class="Playground.Views.ListViewPage"
x:Class="Playground.Views.ItemDetailsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Playground.Views"
Expand All @@ -9,6 +9,9 @@
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>

</Grid>
<TextBlock Text="{Binding Widget.Name}"
FontSize="24"
VerticalAlignment="Center"
HorizontalAlignment="Center" />
</Grid>
</Page>
@@ -0,0 +1,10 @@

namespace Playground.Views;

public sealed partial class ItemDetailsPage : Page
{
public ItemDetailsPage()
{
this.InitializeComponent();
}
}
@@ -0,0 +1,24 @@
<Page
x:Class="Playground.Views.ListPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Playground.Views"
xmlns:vm="using:Playground.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:utu="using:Uno.Toolkit.UI"
xmlns:uen="using:Uno.Extensions.Navigation.UI"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid>
<ListView ItemsSource="{Binding Items}"
uen:Navigation.Request="ItemDetails">
<ListView.ItemTemplate>
<DataTemplate x:Type="vm:ItemDetailsViewModel">
<TextBlock Text="{x:Bind Widget.Name}" FontSize="24"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
@@ -1,9 +1,9 @@

namespace Playground.Views;

public sealed partial class ListViewPage : Page
public sealed partial class ListPage : Page
{
public ListViewPage()
public ListPage()
{
this.InitializeComponent();
}
Expand Down
24 changes: 18 additions & 6 deletions src/Uno.Extensions.Navigation.UI/Navigators/ControlNavigator.cs
Expand Up @@ -175,14 +175,17 @@ protected virtual void UpdateRoute(Route? route)
? new Route(Qualifiers.None, route.Base, null, route.Data) : null;
}

protected async Task<object?> CreateViewModel(IServiceProvider services, NavigationRequest request, Route route, RouteInfo? mapping)
protected async Task<object?> CreateViewModel(
IServiceProvider services,
NavigationRequest request,
Route route,
RouteInfo? mapping)
{
var navigator = services.GetInstance<INavigator>();
if (mapping?.ViewModel is not null)
{
var parameters = route.Data ?? new Dictionary<string, object>();
if (parameters.Any() &&
!parameters.ContainsKey(String.Empty) &&
mapping.FromQuery is not null)
{
var data = await mapping.FromQuery(services, parameters);
Expand All @@ -192,15 +195,24 @@ protected virtual void UpdateRoute(Route? route)
}
}

var dataFactor = services.GetRequiredService<NavigationDataProvider>();
dataFactor.Parameters = route.Data ?? new Dictionary<string, object>();
// Attempt to use the data object passed with navigation
var vm = parameters.TryGetValue(string.Empty, out var navData) &&
navData.GetType().IsSubclassOf(mapping.ViewModel) ? navData : default;

services.AddScopedInstance(request);
if (vm is null)
{
// Attempt to create view model using the DI container
var dataFactor = services.GetRequiredService<NavigationDataProvider>();
dataFactor.Parameters = route.Data ?? new Dictionary<string, object>();

var vm = services.GetService(mapping!.ViewModel);
services.AddScopedInstance(request);

vm = services.GetService(mapping!.ViewModel);
}

if (vm is null)
{
// Attempt to create view model using reflection
try
{
var ctr = mapping.ViewModel.GetNavigationConstructor(navigator!, Region.Services!, out var args);
Expand Down

0 comments on commit 7ade063

Please sign in to comment.