Skip to content

Commit 4a21883

Browse files
authored
Adding Avalonia sample (#159)
* Adding Avalonia sample * WIP * Implement asnyc IsCheckedChanged support * fix asynv save * WIP add some debug data * Improving the debug sample * order items by ID * Adding Avalonia.md to the docs * minor readme improvement * Improve AvaloniaSample - improved Messenger system - Added more comments and explanations * Add sample screenshot to the docs * use nuget instead of project reference * Try fixing review - Added LoggingHandler - Renamed `TodoItem.Content` -> `TodoItem.Title` to match running DataSync-server
1 parent 74df80e commit 4a21883

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2399
-0
lines changed
Loading
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
+++
2+
title = "Avalonia"
3+
+++
4+
5+
## Run the application first
6+
7+
The Avalonia sample uses an in-memory Sqlite store for storing its data. The sample can run on Desktop, Mobile and Browser. To run the application locally:
8+
9+
* [Configure Visual Studio for Avalonia development](https://docs.avaloniaui.net/docs/welcome).
10+
* Open `samples/todoapp/Samples.TodoApp.sln` in Visual Studio.
11+
* In the Solution Explorer, expand the folder `TodoApp.Avalonia` and right-click the `TodoApp.Avalonia.Desktop` project, then select **Set as Startup Project**.
12+
* Select a target (in the top bar), then press F5 to run the application.
13+
14+
> [!TIP]
15+
> We suggest to start testing and debugging using the Desktop App first. Once you feel confident, you can also try out Mobile or Browser version.
16+
17+
> [!NOTE]
18+
> If you bump into issues at this point, please visit [Avalonia.Docs](https://docs.avaloniaui.net) and [Avalonia.Samples](https://github.com/AvaloniaUI/Avalonia.Samples) for some basic getting-started tutorials.
19+
20+
This is how the sample will look like:
21+
![Avalonia sample on Desktop](assets/TodoApp.Avalonia.Desktop.png)
22+
23+
24+
## Deploy a datasync server to Azure
25+
26+
Before you begin adjusting the application for offline usage, you must [deploy a datasync service](../server.md). Make a note of the URI of the service before continuing.
27+
28+
## Update the application for datasync operations
29+
30+
All the changes are isolated to the `Database/AppDbContext.cs` file.
31+
32+
1. Change the definition of the class so that it inherits from `OfflineDbContext`:
33+
34+
```csharp
35+
public class AppDbContext(DbContextOptions<AppDbContext> options) : OfflineDbContext(options)
36+
{
37+
// Rest of the class
38+
}
39+
```
40+
41+
2. Add the `OnDatasyncInitialization()` method:
42+
43+
```csharp
44+
protected override void OnDatasyncInitialization(DatasyncOfflineOptionsBuilder optionsBuilder)
45+
{
46+
HttpClientOptions clientOptions = new()
47+
{
48+
Endpoint = new Uri("https://YOURSITEHERE.azurewebsites.net/"),
49+
HttpPipeline = [new LoggingHandler()]
50+
};
51+
_ = optionsBuilder.UseHttpClientOptions(clientOptions);
52+
}
53+
```
54+
55+
Replace the Endpoint with the URI of your datasync service.
56+
57+
3. Update the `SynchronizeAsync()` method.
58+
59+
The `SynchronizeAsync()` method is used by the application to synchronize data to and from the datasync service. It is called primarily from the `MainViewModel` which drives the UI interactions for the main list.
60+
61+
```csharp
62+
public async Task SynchronizeAsync(CancellationToken cancellationToken = default)
63+
{
64+
PushResult pushResult = await this.PushAsync(cancellationToken);
65+
if (!pushResult.IsSuccessful)
66+
{
67+
throw new ApplicationException($"Push failed: {pushResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}");
68+
}
69+
70+
PullResult pullResult = await this.PullAsync(cancellationToken);
71+
if (!pullResult.IsSuccessful)
72+
{
73+
throw new ApplicationException($"Pull failed: {pullResult.FailedRequests.FirstOrDefault().Value.ReasonPhrase}");
74+
}
75+
}
76+
```
77+
78+
You can now re-run your application. Watch the console logs to show the interactions with the datasync service. Press the refresh button to synchronize data with the cloud. When you restart the application, your changes will automatically populate the database again.
79+
80+
Obviously, you will want to do much more in a "real world" application, including proper error handling, authentication, and using a Sqlite file instead of an in-memory database. This example shows off the minimum required to add datasync services to an application.

samples/todoapp/Samples.TodoApp.sln

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TodoApp.MAUI", "TodoApp.MAU
1515
EndProject
1616
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.WPF", "TodoApp.WPF\TodoApp.WPF.csproj", "{A0996FB8-890D-4E90-A881-01F9EF709711}"
1717
EndProject
18+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TodoApp.Avalonia", "TodoApp.Avalonia", "{9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}"
19+
EndProject
20+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia", "TodoApp.Avalonia\TodoApp.Avalonia\TodoApp.Avalonia.csproj", "{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}"
21+
EndProject
22+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia.Android", "TodoApp.Avalonia\TodoApp.Avalonia.Android\TodoApp.Avalonia.Android.csproj", "{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}"
23+
EndProject
24+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia.Desktop", "TodoApp.Avalonia\TodoApp.Avalonia.Desktop\TodoApp.Avalonia.Desktop.csproj", "{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}"
25+
EndProject
26+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia.iOS", "TodoApp.Avalonia\TodoApp.Avalonia.iOS\TodoApp.Avalonia.iOS.csproj", "{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}"
27+
EndProject
28+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TodoApp.Avalonia.Browser", "TodoApp.Avalonia\TodoApp.Avalonia.Browser\TodoApp.Avalonia.Browser.csproj", "{E8BB1310-477D-44B0-B13E-77F09433D0A3}"
29+
EndProject
1830
Global
1931
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2032
Debug|Any CPU = Debug|Any CPU
@@ -123,12 +135,97 @@ Global
123135
{A0996FB8-890D-4E90-A881-01F9EF709711}.Release|x64.Build.0 = Release|Any CPU
124136
{A0996FB8-890D-4E90-A881-01F9EF709711}.Release|x86.ActiveCfg = Release|Any CPU
125137
{A0996FB8-890D-4E90-A881-01F9EF709711}.Release|x86.Build.0 = Release|Any CPU
138+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
139+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|Any CPU.Build.0 = Debug|Any CPU
140+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
141+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|ARM64.Build.0 = Debug|Any CPU
142+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|x64.ActiveCfg = Debug|Any CPU
143+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|x64.Build.0 = Debug|Any CPU
144+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|x86.ActiveCfg = Debug|Any CPU
145+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Debug|x86.Build.0 = Debug|Any CPU
146+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|Any CPU.ActiveCfg = Release|Any CPU
147+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|Any CPU.Build.0 = Release|Any CPU
148+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|ARM64.ActiveCfg = Release|Any CPU
149+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|ARM64.Build.0 = Release|Any CPU
150+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|x64.ActiveCfg = Release|Any CPU
151+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|x64.Build.0 = Release|Any CPU
152+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|x86.ActiveCfg = Release|Any CPU
153+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A}.Release|x86.Build.0 = Release|Any CPU
154+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
155+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
156+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|ARM64.ActiveCfg = Debug|Any CPU
157+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|ARM64.Build.0 = Debug|Any CPU
158+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|x64.ActiveCfg = Debug|Any CPU
159+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|x64.Build.0 = Debug|Any CPU
160+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|x86.ActiveCfg = Debug|Any CPU
161+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Debug|x86.Build.0 = Debug|Any CPU
162+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
163+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|Any CPU.Build.0 = Release|Any CPU
164+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|ARM64.ActiveCfg = Release|Any CPU
165+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|ARM64.Build.0 = Release|Any CPU
166+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|x64.ActiveCfg = Release|Any CPU
167+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|x64.Build.0 = Release|Any CPU
168+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|x86.ActiveCfg = Release|Any CPU
169+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4}.Release|x86.Build.0 = Release|Any CPU
170+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
171+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
172+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|ARM64.ActiveCfg = Debug|Any CPU
173+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|ARM64.Build.0 = Debug|Any CPU
174+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|x64.ActiveCfg = Debug|Any CPU
175+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|x64.Build.0 = Debug|Any CPU
176+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|x86.ActiveCfg = Debug|Any CPU
177+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Debug|x86.Build.0 = Debug|Any CPU
178+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
179+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|Any CPU.Build.0 = Release|Any CPU
180+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|ARM64.ActiveCfg = Release|Any CPU
181+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|ARM64.Build.0 = Release|Any CPU
182+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|x64.ActiveCfg = Release|Any CPU
183+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|x64.Build.0 = Release|Any CPU
184+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|x86.ActiveCfg = Release|Any CPU
185+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7}.Release|x86.Build.0 = Release|Any CPU
186+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
187+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
188+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|ARM64.ActiveCfg = Debug|Any CPU
189+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|ARM64.Build.0 = Debug|Any CPU
190+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|x64.ActiveCfg = Debug|Any CPU
191+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|x64.Build.0 = Debug|Any CPU
192+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|x86.ActiveCfg = Debug|Any CPU
193+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Debug|x86.Build.0 = Debug|Any CPU
194+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
195+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|Any CPU.Build.0 = Release|Any CPU
196+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|ARM64.ActiveCfg = Release|Any CPU
197+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|ARM64.Build.0 = Release|Any CPU
198+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x64.ActiveCfg = Release|Any CPU
199+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x64.Build.0 = Release|Any CPU
200+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x86.ActiveCfg = Release|Any CPU
201+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1}.Release|x86.Build.0 = Release|Any CPU
202+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
203+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
204+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|ARM64.ActiveCfg = Debug|Any CPU
205+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|ARM64.Build.0 = Debug|Any CPU
206+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|x64.ActiveCfg = Debug|Any CPU
207+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|x64.Build.0 = Debug|Any CPU
208+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|x86.ActiveCfg = Debug|Any CPU
209+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Debug|x86.Build.0 = Debug|Any CPU
210+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
211+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|Any CPU.Build.0 = Release|Any CPU
212+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|ARM64.ActiveCfg = Release|Any CPU
213+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|ARM64.Build.0 = Release|Any CPU
214+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|x64.ActiveCfg = Release|Any CPU
215+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|x64.Build.0 = Release|Any CPU
216+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|x86.ActiveCfg = Release|Any CPU
217+
{E8BB1310-477D-44B0-B13E-77F09433D0A3}.Release|x86.Build.0 = Release|Any CPU
126218
EndGlobalSection
127219
GlobalSection(SolutionProperties) = preSolution
128220
HideSolutionNode = FALSE
129221
EndGlobalSection
130222
GlobalSection(NestedProjects) = preSolution
131223
{2AC73FBE-9E76-4702-B551-B5884383CC68} = {7183ECEC-9F44-48CE-BB97-AA2445170D5E}
224+
{539C6E0F-8F23-4AE0-B8E6-7E72C53B890A} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
225+
{9C2BA2A4-4AD6-4B67-BB6B-29A9024C33C4} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
226+
{3D741850-6FAA-4F36-BD58-F6ECE0CE55D7} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
227+
{DFCE2057-9F7B-4E1A-9C83-B524D9A82FF1} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
228+
{E8BB1310-477D-44B0-B13E-77F09433D0A3} = {9A8B7D7F-1AF1-4C1C-A74A-E422BB680C6E}
132229
EndGlobalSection
133230
GlobalSection(ExtensibilityGlobals) = postSolution
134231
SolutionGuid = {91B9DE2A-8B79-4DC4-8235-216CD07F1CB2}

0 commit comments

Comments
 (0)