Skip to content

Commit

Permalink
feat: Add WinUI3
Browse files Browse the repository at this point in the history
  • Loading branch information
HMBSbige committed Nov 21, 2023
1 parent 84439b5 commit 105168d
Show file tree
Hide file tree
Showing 22 changed files with 667 additions and 6 deletions.
11 changes: 6 additions & 5 deletions NatTypeTester.ViewModels/MainWindowViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using NatTypeTester.Models;
using ReactiveUI;
using STUN;
using System.Collections.Frozen;
using System.Reactive.Linq;
using Volo.Abp.DependencyInjection;

Expand All @@ -19,15 +20,15 @@ public class MainWindowViewModel : ViewModelBase, IScreen

public Config Config => LazyServiceProvider.LazyGetRequiredService<Config>();

private readonly IEnumerable<string> _defaultServers = new HashSet<string>
private static readonly FrozenSet<string> DefaultServers = new[]
{
@"stunserver.stunprotocol.org",
@"stun.fitauto.ru",
@"stun.hot-chilli.net",
@"stun.fitauto.ru",
@"stun.syncthing.net",
@"stun.qq.com",
@"stun.miwifi.com"
};
}.ToFrozenSet();

private SourceList<string> List { get; } = new();
public readonly IObservableCollection<string> StunServers = new ObservableCollectionExtended<string>();
Expand All @@ -43,12 +44,12 @@ public MainWindowViewModel()

public void LoadStunServer()
{
foreach (string? server in _defaultServers)
foreach (string? server in DefaultServers)
{
List.Add(server);
}

Config.StunServer = _defaultServers.First();
Config.StunServer = DefaultServers.First();

Task.Run(() =>
{
Expand Down
2 changes: 1 addition & 1 deletion NatTypeTester.ViewModels/ViewModelBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ namespace NatTypeTester.ViewModels;

public abstract class ViewModelBase : ReactiveObject, ISingletonDependency
{
public IAbpLazyServiceProvider LazyServiceProvider { get; set; } = null!;
public IAbpLazyServiceProvider LazyServiceProvider { get; init; } = null!;
}
14 changes: 14 additions & 0 deletions NatTypeTester.WinUI/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Application
x:Class="NatTypeTester.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
<!-- Other merged dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Other app resources here -->
</ResourceDictionary>
</Application.Resources>
</Application>
19 changes: 19 additions & 0 deletions NatTypeTester.WinUI/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace NatTypeTester;

public partial class App
{
private readonly IAbpApplicationWithInternalServiceProvider _application;

public App()
{
InitializeComponent();
_application = AbpApplicationFactory.Create<NatTypeTesterModule>(options => options.UseAutofac());
_application.Initialize();
_application.ServiceProvider.UseMicrosoftDependencyResolver();
}

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
_application.ServiceProvider.GetRequiredService<MainWindow>().Activate();
}
}
Binary file added NatTypeTester.WinUI/Assets/icon.ico
Binary file not shown.
22 changes: 22 additions & 0 deletions NatTypeTester.WinUI/Extensions/ContentDialogExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace NatTypeTester.Extensions;

internal static class ContentDialogExtensions
{
public static async ValueTask HandleExceptionWithContentDialogAsync(this Exception ex, XamlRoot root)
{
ContentDialog dialog = new();
try
{
dialog.XamlRoot = root;
dialog.Title = nameof(NatTypeTester);
dialog.Content = ex.Message;
dialog.PrimaryButtonText = @"OK";

await dialog.ShowAsync();
}
finally
{
dialog.Hide();
}
}
}
15 changes: 15 additions & 0 deletions NatTypeTester.WinUI/Extensions/DIExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace NatTypeTester.Extensions;

internal static class DIExtension
{
public static T GetRequiredService<T>(this IReadonlyDependencyResolver resolver, string? contract = null) where T : notnull
{
Requires.NotNull(resolver);

T? service = resolver.GetService<T>(contract);

Verify.Operation(service is not null, $@"No service for type {typeof(T)} has been registered.");

return service;
}
}
10 changes: 10 additions & 0 deletions NatTypeTester.WinUI/MainWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Window
x:Class="NatTypeTester.MainWindow"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
>
<Frame x:Name="MainFrame" />
</Window>
25 changes: 25 additions & 0 deletions NatTypeTester.WinUI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
namespace NatTypeTester;

public sealed partial class MainWindow : ISingletonDependency
{
public MainWindow()
{
InitializeComponent();

Title = nameof(NatTypeTester);
ExtendsContentIntoTitleBar = true;

AppWindow.Resize(new SizeInt32(500, 590));
AppWindow.SetIcon(@"Assets\icon.ico");

// CenterScreen
{
DisplayArea displayArea = DisplayArea.GetFromWindowId(AppWindow.Id, DisplayAreaFallback.Nearest);
int x = (displayArea.WorkArea.Width - AppWindow.Size.Width) / 2;
int y = (displayArea.WorkArea.Height - AppWindow.Size.Height) / 2;
AppWindow.Move(new PointInt32(x, y));
}

MainFrame.Navigate(typeof(MainPage));
}
}
37 changes: 37 additions & 0 deletions NatTypeTester.WinUI/NatTypeTester.WinUI.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">

<Import Project="..\common.props" />

<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>NatTypeTester</RootNamespace>
<AssemblyName>NatTypeTester</AssemblyName>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
<Version>8.0.0</Version>
<EnableMsixTooling>true</EnableMsixTooling>
<WindowsPackageType>None</WindowsPackageType>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231115000" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
<PackageReference Include="ReactiveMarbles.ObservableEvents.SourceGenerator" Version="1.3.1" PrivateAssets="all" />
<PackageReference Include="ReactiveUI.WinUI" Version="19.5.1" />
<PackageReference Include="Splat.Microsoft.Extensions.DependencyInjection" Version="14.8.6" />
<PackageReference Include="Volo.Abp.Autofac" Version="7.4.2" />
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\NatTypeTester.ViewModels\NatTypeTester.ViewModels.csproj" />
</ItemGroup>

</Project>
46 changes: 46 additions & 0 deletions NatTypeTester.WinUI/NatTypeTesterModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
global using JetBrains.Annotations;
global using Microsoft;
global using Microsoft.Extensions.DependencyInjection;
global using Microsoft.Extensions.DependencyInjection.Extensions;
global using Microsoft.UI.Windowing;
global using Microsoft.UI.Xaml;
global using Microsoft.UI.Xaml.Controls;
global using Microsoft.VisualStudio.Threading;
global using NatTypeTester.Extensions;
global using NatTypeTester.ViewModels;
global using NatTypeTester.Views;
global using ReactiveMarbles.ObservableEvents;
global using ReactiveUI;
global using Splat;
global using Splat.Microsoft.Extensions.DependencyInjection;
global using STUN.Enums;
global using System.Reactive.Disposables;
global using System.Reactive.Linq;
global using Volo.Abp;
global using Volo.Abp.Autofac;
global using Volo.Abp.DependencyInjection;
global using Volo.Abp.Modularity;
global using Windows.Graphics;
global using Windows.System;

namespace NatTypeTester;

[DependsOn(
typeof(AbpAutofacModule),
typeof(NatTypeTesterViewModelModule)
)]
[UsedImplicitly]
internal class NatTypeTesterModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
context.Services.UseMicrosoftDependencyResolver();
Locator.CurrentMutable.InitializeSplat();
Locator.CurrentMutable.InitializeReactiveUI(RegistrationNamespace.WinUI);
}

public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.TryAddTransient<RoutingState>();
}
}
75 changes: 75 additions & 0 deletions NatTypeTester.WinUI/Views/MainPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<views:MainReactivePage
x:Class="NatTypeTester.Views.MainPage"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:NatTypeTester.Views"
xmlns:reactiveUi="using:ReactiveUI"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

<Grid RowDefinitions="28,Auto,*" >

<!-- TitleBar -->
<StackPanel
Padding="8,0,0,0"
Orientation="Horizontal"
Spacing="5">
<Image Height="16" Source="/Assets/icon.ico" />
<TextBlock
Style="{StaticResource CaptionTextBlockStyle}"
VerticalAlignment="Center"
Text="NatTypeTester" />
</StackPanel>

<StackPanel Grid.Row="1">
<ComboBox x:Name="ServersComboBox"
Margin="10,10"
IsEditable="True"
Header="STUN Server"
HorizontalAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding }"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>

<NavigationView
Grid.Row="2"
x:Name="NavigationView"
IsBackEnabled="False"
IsBackButtonVisible="Collapsed"
PaneDisplayMode="LeftCompact"
IsPaneOpen="False">

<NavigationView.MenuItems>
<NavigationViewItem Content="RFC 5780" Tag="1">
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xEDA3;" />
</NavigationViewItem.Icon>
</NavigationViewItem>
<NavigationViewItem Content="RFC 3489" Tag="2">
<NavigationViewItem.Icon>
<FontIcon Glyph="&#xE969;" />
</NavigationViewItem.Icon>
</NavigationViewItem>
</NavigationView.MenuItems>

<reactiveUi:RoutedViewHost
x:Name="RoutedViewHost"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<reactiveUi:RoutedViewHost.ContentTransitions>
<TransitionCollection>
<ContentThemeTransition />
</TransitionCollection>
</reactiveUi:RoutedViewHost.ContentTransitions>
</reactiveUi:RoutedViewHost>

</NavigationView>

</Grid>
</views:MainReactivePage>
58 changes: 58 additions & 0 deletions NatTypeTester.WinUI/Views/MainPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
namespace NatTypeTester.Views;

internal sealed partial class MainPage
{
public MainPage()
{
InitializeComponent();
ViewModel = Locator.Current.GetRequiredService<MainWindowViewModel>();

IAbpLazyServiceProvider serviceProvider = Locator.Current.GetRequiredService<IAbpLazyServiceProvider>();

this.WhenActivated(d =>
{
this.Bind(ViewModel,
vm => vm.Config.StunServer,
v => v.ServersComboBox.Text
).DisposeWith(d);

this.OneWayBind(ViewModel,
vm => vm.StunServers,
v => v.ServersComboBox.ItemsSource
).DisposeWith(d);

this.OneWayBind(ViewModel, vm => vm.Router, v => v.RoutedViewHost.Router).DisposeWith(d);

NavigationView.Events().SelectionChanged.Subscribe(parameter =>
{
if (parameter.args.IsSettingsSelected)
{
ViewModel.Router.Navigate.Execute(serviceProvider.LazyGetRequiredService<SettingViewModel>()).Subscribe().Dispose();
return;
}

if (parameter.args.SelectedItem is not NavigationViewItem { Tag: string tag })
{
return;
}

switch (tag)
{
case @"1":
{
ViewModel.Router.Navigate.Execute(serviceProvider.LazyGetRequiredService<RFC5780ViewModel>()).Subscribe().Dispose();
break;
}
case @"2":
{
ViewModel.Router.Navigate.Execute(serviceProvider.LazyGetRequiredService<RFC3489ViewModel>()).Subscribe().Dispose();
break;
}
}
}).DisposeWith(d);
NavigationView.SelectedItem = NavigationView.MenuItems.OfType<NavigationViewItem>().First();

ViewModel.LoadStunServer();
});
}
}
Loading

0 comments on commit 105168d

Please sign in to comment.