Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Demo applications are located in the [`demos/`](./demos/) directory. Also see ou
### Command-Line

- [demos/CommandLine](./demos/CommandLine/README.md): A CLI to-do list example app using a Node-js backend.
- [demos/WPF](./demos/WPF/README.md): This is a demo WPF application that showcases how to use the [PowerSync SDK](https://www.powersync.com) for data synchronization in a to-do list application using a Node-js backend.

# Supported Frameworks

Expand Down
3 changes: 2 additions & 1 deletion demos/CommandLine/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
user_id.txt
user_id.txt
.env
13 changes: 13 additions & 0 deletions demos/WPF/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": 1,
"isRoot": true,
"tools": {
"csharpier": {
"version": "0.30.6",
"commands": [
"dotnet-csharpier"
],
"rollForward": false
}
}
}
2 changes: 2 additions & 0 deletions demos/WPF/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
BACKEND_URL=
POWERSYNC_URL=
66 changes: 66 additions & 0 deletions demos/WPF/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
## A streamlined .gitignore for modern .NET projects
## including temporary files, build results, and
## files generated by popular .NET tools. If you are
## developing with Visual Studio, the VS .gitignore
## https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
## has more thorough IDE-specific entries.
##
## Get latest from https://github.com/github/gitignore/blob/main/Dotnet.gitignore

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/

# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/

# ASP.NET Scaffolding
ScaffoldingReadMe.txt

# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg

# Others
~$*
*~
CodeCoverage/

# MSBuild Binary and Structured Log
*.binlog

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml

*.txt

*.db
*.db-shm
*.db-wal

fe.pug
fe/

.env

9 changes: 9 additions & 0 deletions demos/WPF/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Application x:Class="PowersyncDotnetTodoList.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:PowersyncDotnetTodoList.Converters">
<Application.Resources>
<converters:BoolToStatusConverter x:Key="BoolToStatusConverter"/>
<converters:StringToVisibilityConverter x:Key="StringToVisibilityConverter"/>
</Application.Resources>
</Application>
90 changes: 90 additions & 0 deletions demos/WPF/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System.Diagnostics;
using System.Windows;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PowerSync.Common.Client;
using PowersyncDotnetTodoList.Models;
using PowersyncDotnetTodoList.Services;
using PowersyncDotnetTodoList.ViewModels;
using PowersyncDotnetTodoList.Views;

namespace PowersyncDotnetTodoList
{
public partial class App : Application
{
public static IServiceProvider? Services { get; private set; }

protected override async void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

var services = new ServiceCollection();
ConfigureServices(services);

// Build the service provider
Services = services.BuildServiceProvider();

// Initialize the database and connector
var db = Services.GetRequiredService<PowerSyncDatabase>();
var connector = Services.GetRequiredService<PowerSyncConnector>();
await db.Init();
await db.Connect(connector);
await db.WaitForFirstSync();

var mainWindow = Services.GetRequiredService<MainWindow>();

var navigationService = Services.GetRequiredService<INavigationService>();
navigationService.Navigate<TodoListViewModel>();

mainWindow.Show();
}

private void ConfigureServices(IServiceCollection services)
{
ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Information);
});

// Register PowerSyncDatabase
services.AddSingleton<PowerSyncDatabase>(sp =>
{
var logger = loggerFactory.CreateLogger("PowerSyncLogger");
return new PowerSyncDatabase(
new PowerSyncDatabaseOptions
{
Database = new SQLOpenOptions { DbFilename = "example.db" },
Schema = AppSchema.PowerSyncSchema,
Logger = logger,
}
);
});

// Register IPowerSyncDatabase explicitly
services.AddSingleton<IPowerSyncDatabase>(sp =>
sp.GetRequiredService<PowerSyncDatabase>()
);

// Register PowerSyncConnector
services.AddSingleton<PowerSyncConnector>();

// Register ViewModels and Views
services.AddTransient<TodoListViewModel>();
services.AddTransient<TodoViewModel>();
services.AddTransient<SQLConsoleViewModel>();
services.AddTransient<TodoListView>();
services.AddTransient<TodoView>();
services.AddTransient<SQLConsoleView>();

services.AddSingleton<MainWindow>();
services.AddSingleton<MainWindowViewModel>();

services.AddSingleton<INavigationService>(sp =>
{
var mainWindow = sp.GetRequiredService<MainWindow>();
return new NavigationService(mainWindow.MainFrame, sp);
});
}
}
}
10 changes: 10 additions & 0 deletions demos/WPF/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

[assembly:ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
Binary file added demos/WPF/Assets/Icons/icon-192x192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/WPF/Assets/Icons/icon-256x256.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/WPF/Assets/Icons/icon-384x384.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/WPF/Assets/Icons/icon-512x512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demos/WPF/Assets/Icons/icon.ico
Binary file not shown.
Binary file added demos/WPF/Assets/Icons/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions demos/WPF/Converters/BoolStatusConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Globalization;
using System.Windows.Data;

namespace PowersyncDotnetTodoList.Converters
{
public class BoolToStatusConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool connected)
{
return connected ? "Connected" : "Disconnected";
}
return "Disconnected"; // Default if the value isn't a boolean
}

public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture
)
{
return value is string str && str == "Connected";
}
}
}
26 changes: 26 additions & 0 deletions demos/WPF/Converters/StringToVisibilityConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Globalization;
using System.Windows;
using System.Windows.Data;

namespace PowersyncDotnetTodoList.Converters
{
public class StringToVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.IsNullOrEmpty(value as string)
? Visibility.Collapsed
: Visibility.Visible;
}

public object ConvertBack(
object value,
Type targetType,
object parameter,
CultureInfo culture
)
{
return Visibility.Visible;
}
}
}
Loading