Skip to content

Commit ba322cb

Browse files
authored
(#273) .NET9 MAUI Implementation. (#282)
1 parent e8f7fd9 commit ba322cb

20 files changed

+8541
-115
lines changed

samples/todoapp/Samples.TodoApp.sln

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApp.WinUI3", "TodoApp.W
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Sample.Datasync.Server", "..\datasync-server\src\Sample.Datasync.Server\Sample.Datasync.Server.csproj", "{E67734DD-B397-4A65-AA50-D62F37EF05DD}"
99
EndProject
10-
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApp.MAUI", "TodoApp.MAUI\TodoApp.MAUI.csproj", "{00430043-04C5-4F8F-87A9-98ECC0051808}"
11-
EndProject
1210
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.WPF", "TodoApp.WPF\TodoApp.WPF.csproj", "{A0996FB8-890D-4E90-A881-01F9EF709711}"
1311
EndProject
1412
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TodoApp.Avalonia", "TodoApp.Avalonia", "{9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}"
@@ -30,6 +28,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Server", "Server", "{AF5C47
3028
EndProject
3129
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Clients", "Clients", "{32025F6A-2D8A-4BA2-93BE-B989DFD216FC}"
3230
EndProject
31+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.MAUI", "TodoApp.MAUI\TodoApp.MAUI.csproj", "{46F53DE6-0B72-4644-B55F-3A96C72C852F}"
32+
EndProject
3333
Global
3434
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3535
Debug|Any CPU = Debug|Any CPU
@@ -82,30 +82,6 @@ Global
8282
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x64.Build.0 = Release|Any CPU
8383
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x86.ActiveCfg = Release|Any CPU
8484
{E67734DD-B397-4A65-AA50-D62F37EF05DD}.Release|x86.Build.0 = Release|Any CPU
85-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
86-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|Any CPU.Build.0 = Debug|Any CPU
87-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
88-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|ARM64.ActiveCfg = Debug|Any CPU
89-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|ARM64.Build.0 = Debug|Any CPU
90-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|ARM64.Deploy.0 = Debug|Any CPU
91-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|x64.ActiveCfg = Debug|Any CPU
92-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|x64.Build.0 = Debug|Any CPU
93-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|x64.Deploy.0 = Debug|Any CPU
94-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|x86.ActiveCfg = Debug|Any CPU
95-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|x86.Build.0 = Debug|Any CPU
96-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Debug|x86.Deploy.0 = Debug|Any CPU
97-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|Any CPU.ActiveCfg = Release|Any CPU
98-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|Any CPU.Build.0 = Release|Any CPU
99-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|Any CPU.Deploy.0 = Release|Any CPU
100-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|ARM64.ActiveCfg = Release|Any CPU
101-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|ARM64.Build.0 = Release|Any CPU
102-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|ARM64.Deploy.0 = Release|Any CPU
103-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|x64.ActiveCfg = Release|Any CPU
104-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|x64.Build.0 = Release|Any CPU
105-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|x64.Deploy.0 = Release|Any CPU
106-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|x86.ActiveCfg = Release|Any CPU
107-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|x86.Build.0 = Release|Any CPU
108-
{00430043-04C5-4F8F-87A9-98ECC0051808}.Release|x86.Deploy.0 = Release|Any CPU
10985
{A0996FB8-890D-4E90-A881-01F9EF709711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
11086
{A0996FB8-890D-4E90-A881-01F9EF709711}.Debug|Any CPU.Build.0 = Debug|Any CPU
11187
{A0996FB8-890D-4E90-A881-01F9EF709711}.Debug|ARM64.ActiveCfg = Debug|Any CPU
@@ -186,20 +162,37 @@ Global
186162
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x64.Build.0 = Release|Any CPU
187163
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x86.ActiveCfg = Release|Any CPU
188164
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x86.Build.0 = Release|Any CPU
165+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
166+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|Any CPU.Build.0 = Debug|Any CPU
167+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
168+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
169+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|ARM64.Build.0 = Debug|Any CPU
170+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|x64.ActiveCfg = Debug|Any CPU
171+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|x64.Build.0 = Debug|Any CPU
172+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|x86.ActiveCfg = Debug|Any CPU
173+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Debug|x86.Build.0 = Debug|Any CPU
174+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|Any CPU.ActiveCfg = Release|Any CPU
175+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|Any CPU.Build.0 = Release|Any CPU
176+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|ARM64.ActiveCfg = Release|Any CPU
177+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|ARM64.Build.0 = Release|Any CPU
178+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|x64.ActiveCfg = Release|Any CPU
179+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|x64.Build.0 = Release|Any CPU
180+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|x86.ActiveCfg = Release|Any CPU
181+
{46F53DE6-0B72-4644-B55F-3A96C72C852F}.Release|x86.Build.0 = Release|Any CPU
189182
EndGlobalSection
190183
GlobalSection(SolutionProperties) = preSolution
191184
HideSolutionNode = FALSE
192185
EndGlobalSection
193186
GlobalSection(NestedProjects) = preSolution
194187
{D783EDE7-D3A2-44D3-8C97-38AFFF9A4555} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC}
195188
{E67734DD-B397-4A65-AA50-D62F37EF05DD} = {AF5C479C-1BDE-4783-8707-A3440FC0B89D}
196-
{00430043-04C5-4F8F-87A9-98ECC0051808} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC}
197189
{A0996FB8-890D-4E90-A881-01F9EF709711} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC}
198190
{9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC}
199191
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
200192
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
201193
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
202194
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
195+
{46F53DE6-0B72-4644-B55F-3A96C72C852F} = {32025F6A-2D8A-4BA2-93BE-B989DFD216FC}
203196
EndGlobalSection
204197
GlobalSection(ExtensibilityGlobals) = postSolution
205198
SolutionGuid = {91B9DE2A-8B79-4DC4-8235-216CD07F1CB2}

samples/todoapp/TodoApp.MAUI/App.xaml.cs

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
using Windows.Graphics;
99
#endif
1010

11-
using Microsoft.Data.Sqlite;
1211
using Microsoft.EntityFrameworkCore;
1312
using TodoApp.MAUI.Models;
14-
using TodoApp.MAUI.ViewModels;
1513
using TodoApp.MAUI.Services;
14+
using TodoApp.MAUI.ViewModels;
1615

1716
namespace TodoApp.MAUI;
1817

@@ -23,25 +22,22 @@ public partial class App : Application, IDisposable
2322
const int WindowHeight = 800;
2423
#endif
2524

26-
private readonly SqliteConnection dbConnection;
27-
28-
public IServiceProvider Services { get; }
29-
3025
public App()
3126
{
3227
InitializeComponent();
3328

34-
this.dbConnection = new SqliteConnection("Data Source=:memory:");
35-
this.dbConnection.Open();
36-
3729
Services = new ServiceCollection()
3830
.AddTransient<MainViewModel>()
3931
.AddTransient<IAlertService, AlertService>()
4032
.AddScoped<IDbInitializer, DbContextInitializer>()
41-
.AddDbContext<AppDbContext>(options => options.UseSqlite(this.dbConnection))
33+
.AddDbContext<AppDbContext>(options => options.UseSqlite(SqliteHelper.Connection))
4234
.BuildServiceProvider();
4335

44-
InitializeDatabase();
36+
using (IServiceScope scope = Services.CreateScope())
37+
{
38+
IDbInitializer initializer = scope.ServiceProvider.GetRequiredService<IDbInitializer>();
39+
initializer.Initialize();
40+
}
4541

4642
Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
4743
{
@@ -53,24 +49,15 @@ public App()
5349
appWindow.Resize(new SizeInt32(WindowWidth, WindowHeight));
5450
#endif
5551
});
56-
MainPage = new NavigationPage(new MainPage());
5752
}
5853

59-
private void InitializeDatabase()
54+
public IServiceProvider Services { get; }
55+
56+
protected override Window CreateWindow(IActivationState? activationState)
6057
{
61-
using IServiceScope scope = Services.CreateScope();
62-
IDbInitializer initializer = scope.ServiceProvider.GetRequiredService<IDbInitializer>();
63-
initializer.Initialize();
58+
return new Window(new AppShell());
6459
}
6560

66-
/// <summary>
67-
/// A helper method for getting a service from the services collection.
68-
/// </summary>
69-
/// <typeparam name="TService">The type of the service.</typeparam>
70-
/// <returns>An instance of the service</returns>
71-
public static TService GetRequiredService<TService>() where TService : notnull
72-
=> ((App)App.Current!).Services.GetRequiredService<TService>();
73-
7461
#region IDisposable
7562
private bool hasDisposed;
7663

@@ -80,7 +67,7 @@ protected virtual void Dispose(bool disposing)
8067
{
8168
if (disposing)
8269
{
83-
this.dbConnection.Close();
70+
SqliteHelper.Connection.Dispose();
8471
}
8572

8673
this.hasDisposed = true;
@@ -93,4 +80,4 @@ public void Dispose()
9380
GC.SuppressFinalize(this);
9481
}
9582
#endregion
96-
}
83+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Shell
3+
x:Class="TodoApp.MAUI.AppShell"
4+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
xmlns:local="clr-namespace:TodoApp.MAUI"
7+
Shell.FlyoutBehavior="Flyout"
8+
Title="TodoApp.MAUI">
9+
10+
<ShellContent
11+
Title="Home"
12+
ContentTemplate="{DataTemplate local:MainPage}"
13+
Route="MainPage" />
14+
15+
</Shell>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace TodoApp.MAUI;
6+
7+
public partial class AppShell : Shell
8+
{
9+
public AppShell()
10+
{
11+
InitializeComponent();
12+
}
13+
}

samples/todoapp/TodoApp.MAUI/MainPage.xaml

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,6 @@
77
xmlns:viewmodels="clr-namespace:TodoApp.MAUI.ViewModels"
88
Title="TodoApp"
99
x:DataType="viewmodels:MainViewModel">
10-
<NavigationPage.TitleView>
11-
<StackLayout Style="{StaticResource titleViewContainer}">
12-
<Label Style="{StaticResource titleViewLabel}">TodoApp</Label>
13-
<ImageButton Command="{Binding RefreshItemsCommand}" Style="{StaticResource titleViewRefreshIcon}" />
14-
</StackLayout>
15-
</NavigationPage.TitleView>
1610

1711
<Grid
1812
AbsoluteLayout.LayoutBounds="0,0,1,1"
@@ -51,17 +45,26 @@
5145
</ListView.ItemTemplate>
5246
</ListView>
5347

54-
<!-- Entry box -->
55-
<Frame Grid.Row="1" Style="{StaticResource roundedCornerFrame}">
56-
<HorizontalStackLayout>
57-
<Image Style="{StaticResource addItemIcon}" />
58-
<Entry
59-
x:Name="addItemEntry"
60-
Placeholder="Enter Todo Item Text"
61-
ReturnCommand="{Binding AddItemCommand}"
62-
ReturnCommandParameter="{Binding Text, Source={x:Reference addItemEntry}}"
63-
Style="{StaticResource addItemEntry}" />
64-
</HorizontalStackLayout>
65-
</Frame>
48+
<Grid Grid.Row="1" ColumnDefinitions="*,Auto">
49+
<Border Grid.Column="0" Style="{StaticResource roundedCornerFrame}">
50+
<Grid ColumnDefinitions="Auto,*">
51+
<Image Grid.Column="0" Style="{StaticResource addItemIcon}" />
52+
<Entry
53+
x:Name="addItemEntry"
54+
Grid.Column="1"
55+
Completed="OnAddItemEntryCompleted"
56+
Placeholder="Enter Todo Item Text"
57+
ReturnCommand="{Binding AddItemCommand}"
58+
ReturnCommandParameter="{Binding Text, Source={x:Reference addItemEntry}}"
59+
Style="{StaticResource addItemEntry}" />
60+
</Grid>
61+
</Border>
62+
<ImageButton
63+
Grid.Column="1"
64+
Command="{Binding RefreshItemsCommand}"
65+
Style="{StaticResource refreshItemIcon}" />
66+
</Grid>
67+
6668
</Grid>
6769
</ContentPage>
70+

samples/todoapp/TodoApp.MAUI/MainPage.xaml.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public partial class MainPage : ContentPage
1414
public MainPage()
1515
{
1616
InitializeComponent();
17-
this._viewModel = App.GetRequiredService<MainViewModel>();
17+
this._viewModel = ((App)App.Current!).Services.GetRequiredService<MainViewModel>();
1818
BindingContext = this._viewModel;
1919
}
2020

@@ -36,5 +36,14 @@ public void OnListItemTapped(object sender, ItemTappedEventArgs e)
3636
itemList.SelectedItem = null;
3737
}
3838
}
39+
40+
public void OnAddItemEntryCompleted(object sender, EventArgs e)
41+
{
42+
if (sender is not null and Entry entry)
43+
{
44+
this._viewModel.AddItemCommand.Execute(entry.Text);
45+
entry.Text = string.Empty;
46+
}
47+
}
3948
}
4049

samples/todoapp/TodoApp.MAUI/MauiProgram.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Licensed to the .NET Foundation under one or more agreements.
1+
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

@@ -9,7 +9,7 @@ public static class MauiProgram
99
{
1010
public static MauiApp CreateMauiApp()
1111
{
12-
MauiAppBuilder builder = MauiApp.CreateBuilder();
12+
var builder = MauiApp.CreateBuilder();
1313
builder
1414
.UseMauiApp<App>()
1515
.ConfigureFonts(fonts =>

samples/todoapp/TodoApp.MAUI/Platforms/Windows/Package.appxmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0" />
1010

11-
<mp:PhoneIdentity PhoneProductId="91956ED2-D48D-42FC-A0B7-FEC593F70038" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
11+
<mp:PhoneIdentity PhoneProductId="7F57A5B1-4CD1-4C7A-BCE1-BCDD189674D4" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
1212

1313
<Properties>
1414
<DisplayName>$placeholder$</DisplayName>

samples/todoapp/TodoApp.MAUI/Properties/launchSettings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"profiles": {
33
"Windows Machine": {
4-
"commandName": "MsixPackage",
4+
"commandName": "Project",
55
"nativeDebugging": false
66
}
77
}

0 commit comments

Comments
 (0)