Setup ShellPage and Loading Placeholder

This commit is contained in:
Michael Hawker
2024-09-17 15:56:28 -07:00
parent c92800fc32
commit 12f29ab6a3
13 changed files with 219 additions and 75 deletions

View File

@@ -0,0 +1,19 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace Microsoft.CmdPal.UI.ViewModels;
public partial class ShellViewModel : ObservableObject
{
[RelayCommand]
public async Task<bool> LoadAsync()
{
await Task.Delay(2000);
return true;
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Microsoft.CmdPal.UI.ListPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Interactions="using:Microsoft.Xaml.Interactions.Core"
xmlns:Interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Page.Resources>
<!-- https://learn.microsoft.com/en-us/windows/apps/design/controls/itemsview#specify-the-look-of-the-items -->
<DataTemplate x:Key="ListItemViewModelTemplate" x:DataType="viewmodels:ListItemViewModel">
<ItemContainer AutomationProperties.Name="{x:Bind Header}">
<StackPanel Background="{ThemeResource SystemControlBackgroundBaseMediumBrush}" Orientation="Horizontal">
<TextBlock Text="{x:Bind Header}" />
<TextBlock Foreground="{ThemeResource SystemAccentColor}" Text="{x:Bind SubHeader}" />
</StackPanel>
</ItemContainer>
</DataTemplate>
</Page.Resources>
<Grid>
<!-- not using Interactivity:Interaction.Behaviors due to wanting to do AoT -->
<ItemsView
IsItemInvokedEnabled="True"
ItemInvoked="ItemsView_ItemInvoked"
ItemTemplate="{StaticResource ListItemViewModelTemplate}"
ItemsSource="{x:Bind ViewModel.Items}" />
</Grid>
</Page>

View File

@@ -10,11 +10,11 @@ namespace Microsoft.CmdPal.UI;
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
public sealed partial class ListPage : Page
{
public ListViewModel ViewModel { get; set; } = new();
public MainPage()
public ListPage()
{
this.InitializeComponent();
ViewModel.Items.Add(new ListItemViewModel { Header = "Hello", SubHeader = "World" });

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Microsoft.CmdPal.UI.LoadingPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid>
<ProgressRing
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True" />
</Grid>
</Page>

View File

@@ -0,0 +1,53 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.WinUI;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Microsoft.UI.Xaml.Navigation;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace Microsoft.CmdPal.UI;
/// <summary>
/// We use this page to do initialization of our extensions and cache loading to hydrate our ViewModels.
/// </summary>
public sealed partial class LoadingPage : Page
{
private readonly DispatcherQueue _queue = DispatcherQueue.GetForCurrentThread();
public LoadingPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.Parameter is ShellViewModel shellVM
&& shellVM.LoadCommand != null)
{
shellVM.LoadCommand.Execute(null);
_ = Task.Run(async () =>
{
await shellVM.LoadCommand.ExecutionTask!;
if (shellVM.LoadCommand.ExecutionTask.Status == TaskStatus.RanToCompletion)
{
await _queue.EnqueueAsync(() =>
{
Frame.Navigate(typeof(ListPage), new ListViewModel(), new DrillInNavigationTransitionInfo());
});
}
// TODO: Handle failure case
});
}
base.OnNavigatedTo(e);
}
}

View File

@@ -1,51 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Page
x:Class="Microsoft.CmdPal.UI.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
xmlns:controls="using:Microsoft.CmdPal.UI.Controls"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.Resources>
<!-- https://learn.microsoft.com/en-us/windows/apps/design/controls/itemsview#specify-the-look-of-the-items -->
<DataTemplate x:Key="ListItemViewModelTemplate" x:DataType="viewmodels:ListItemViewModel">
<ItemContainer
AutomationProperties.Name="{x:Bind Header}">
<StackPanel
Orientation="Horizontal"
Background="{ThemeResource SystemControlBackgroundBaseMediumBrush}">
<TextBlock
Text="{x:Bind Header}" />
<TextBlock
Text="{x:Bind SubHeader}"
Foreground="{ThemeResource SystemAccentColor}"/>
</StackPanel>
</ItemContainer>
</DataTemplate>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:SearchBar
Grid.Row="0"
VerticalAlignment="Top" />
<!-- not using Interactivity:Interaction.Behaviors due to wanting to do AoT -->
<ItemsView
Grid.Row="1"
IsItemInvokedEnabled="True"
ItemsSource="{x:Bind ViewModel.Items}"
ItemTemplate="{StaticResource ListItemViewModelTemplate}"
ItemInvoked="ItemsView_ItemInvoked" />
</Grid>
</Page>

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<Window
x:Class="Microsoft.CmdPal.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewmodels="using:Microsoft.CmdPal.UI.ViewModels"
mc:Ignorable="d">
<Frame Name="RootFrame" />
<local:ShellPage />
</Window>

View File

@@ -13,28 +13,10 @@ namespace Microsoft.CmdPal.UI;
/// <summary>
/// An empty window that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainWindow : Window, IRecipient<NavigateToDetailsMessage>, IRecipient<NavigateBackMessage>
public sealed partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// how we are doing navigation around
WeakReferenceMessenger.Default.RegisterAll(this);
RootFrame.Navigate(typeof(MainPage));
}
public void Receive(NavigateToDetailsMessage message)
{
RootFrame.Navigate(typeof(ListDetailPage), message.ListItem);
}
public void Receive(NavigateBackMessage message)
{
if (RootFrame.CanGoBack)
{
RootFrame.GoBack();
}
}
}

View File

@@ -14,7 +14,9 @@
<ItemGroup>
<None Remove="Controls\SearchBar.xaml" />
<None Remove="ListDetailPage.xaml" />
<None Remove="LoadingPage.xaml" />
<None Remove="MainPage.xaml" />
<None Remove="ShellPage.xaml" />
<None Remove="Styles\Button.xaml" />
<None Remove="Styles\TextBox.xaml" />
</ItemGroup>
@@ -31,6 +33,7 @@
<ItemGroup>
<PackageReference Include="CommunityToolkit.WinUI.Converters" />
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
<PackageReference Include="Microsoft.WindowsAppSDK" />
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" />
@@ -49,6 +52,16 @@
<ItemGroup>
<ProjectReference Include="..\Microsoft.CmdPal.UI.ViewModels\Microsoft.CmdPal.UI.ViewModels.csproj" />
</ItemGroup>
<ItemGroup>
<Page Update="LoadingPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="ShellPage.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Page Update="ListDetailPage.xaml">

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Microsoft.CmdPal.UI.ShellPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.CmdPal.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:Microsoft.CmdPal.UI"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<controls:SearchBar Grid.Row="0" VerticalAlignment="Top" />
<Frame
Name="RootFrame"
Grid.Row="1"
IsNavigationStackEnabled="True" />
<!-- TODO: Actions Bar/Control Here -->
</Grid>
</Page>

View File

@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.UI.Xaml.Controls;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace Microsoft.CmdPal.UI;
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class ShellPage :
Page,
IRecipient<NavigateToDetailsMessage>,
IRecipient<NavigateBackMessage>
{
public ShellViewModel ViewModel { get; private set; } = new ShellViewModel();
public ShellPage()
{
this.InitializeComponent();
// how we are doing navigation around
WeakReferenceMessenger.Default.RegisterAll(this);
RootFrame.Navigate(typeof(LoadingPage), ViewModel);
}
public void Receive(NavigateToDetailsMessage message)
{
RootFrame.Navigate(typeof(ListDetailPage), message.ListItem);
}
public void Receive(NavigateBackMessage message)
{
if (RootFrame.CanGoBack)
{
RootFrame.GoBack();
}
}
}