mirror of
https://github.com/jie65535/ChineseChess.git
synced 2024-07-27 18:55:00 +08:00
1. 移除 ChineseChess.GUI 项目
抱歉,这框架用在这上面,真是用镭射炮打苍蝇,又啰嗦又难用。 我觉得WinForm比较适合这项目,就这样了。 2. 新增 ChineseChess 项目,选择WinForm框架,使用.NET 5.0(总要试试)
This commit is contained in:
parent
66af740423
commit
aba97a033f
@ -1,15 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<RootNamespace>ChineseChess.GUI.Core</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Models\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,11 +0,0 @@
|
||||
namespace ChineseChess.GUI.Core.Contracts.Services
|
||||
{
|
||||
public interface IFileService
|
||||
{
|
||||
T Read<T>(string folderPath, string fileName);
|
||||
|
||||
void Save<T>(string folderPath, string fileName, T content);
|
||||
|
||||
void Delete(string folderPath, string fileName);
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using ChineseChess.GUI.Core.Contracts.Services;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ChineseChess.GUI.Core.Services
|
||||
{
|
||||
public class FileService : IFileService
|
||||
{
|
||||
public T Read<T>(string folderPath, string fileName)
|
||||
{
|
||||
var path = Path.Combine(folderPath, fileName);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
var json = File.ReadAllText(path);
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public void Save<T>(string folderPath, string fileName, T content)
|
||||
{
|
||||
if (!Directory.Exists(folderPath))
|
||||
{
|
||||
Directory.CreateDirectory(folderPath);
|
||||
}
|
||||
|
||||
var fileContent = JsonConvert.SerializeObject(content);
|
||||
File.WriteAllText(Path.Combine(folderPath, fileName), fileContent, Encoding.UTF8);
|
||||
}
|
||||
|
||||
public void Delete(string folderPath, string fileName)
|
||||
{
|
||||
if (fileName != null && File.Exists(Path.Combine(folderPath, fileName)))
|
||||
{
|
||||
File.Delete(Path.Combine(folderPath, fileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
This core project is a .net standard project.
|
||||
It's a great place to put all your logic that is not platform dependent (e.g. model/helper classes) so they can be reused.
|
@ -1,35 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<AssetTargetFallback>uap10.0.18362</AssetTargetFallback>
|
||||
<Platforms>x64;x86;AnyCPU</Platforms>
|
||||
<RootNamespace>ChineseChess.GUI.Tests.xUnit</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="3.0.3" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
|
||||
<PackageReference Include="Moq" Version="4.16.1" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ChineseChess.GUI\ChineseChess.GUI.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -1,98 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Core.Contracts.Services;
|
||||
using ChineseChess.GUI.Core.Services;
|
||||
using ChineseChess.GUI.Models;
|
||||
using ChineseChess.GUI.Services;
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
using ChineseChess.GUI.Views;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace ChineseChess.GUI.Tests.XUnit
|
||||
{
|
||||
public class PagesTests
|
||||
{
|
||||
private readonly IHost _host;
|
||||
|
||||
public PagesTests()
|
||||
{
|
||||
var appLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
|
||||
_host = Host.CreateDefaultBuilder()
|
||||
.ConfigureAppConfiguration(c => c.SetBasePath(appLocation))
|
||||
.ConfigureServices(ConfigureServices)
|
||||
.Build();
|
||||
}
|
||||
|
||||
private void ConfigureServices(HostBuilderContext context, IServiceCollection services)
|
||||
{
|
||||
// Core Services
|
||||
services.AddSingleton<IFileService, FileService>();
|
||||
|
||||
// Services
|
||||
services.AddSingleton<IThemeSelectorService, ThemeSelectorService>();
|
||||
services.AddSingleton<ISystemService, SystemService>();
|
||||
services.AddSingleton<IPersistAndRestoreService, PersistAndRestoreService>();
|
||||
services.AddSingleton<IApplicationInfoService, ApplicationInfoService>();
|
||||
services.AddSingleton<IPageService, PageService>();
|
||||
services.AddSingleton<INavigationService, NavigationService>();
|
||||
|
||||
// ViewModels
|
||||
services.AddTransient<SettingsViewModel>();
|
||||
services.AddTransient<MainViewModel>();
|
||||
|
||||
// Configuration
|
||||
services.Configure<AppConfig>(context.Configuration.GetSection(nameof(AppConfig)));
|
||||
}
|
||||
|
||||
// TODO WTS: Add tests for functionality you add to SettingsViewModel.
|
||||
[Fact]
|
||||
public void TestSettingsViewModelCreation()
|
||||
{
|
||||
var vm = _host.Services.GetService(typeof(SettingsViewModel));
|
||||
Assert.NotNull(vm);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestGetSettingsPageType()
|
||||
{
|
||||
if (_host.Services.GetService(typeof(IPageService)) is IPageService pageService)
|
||||
{
|
||||
var pageType = pageService.GetPageType(typeof(SettingsViewModel).FullName);
|
||||
Assert.Equal(typeof(SettingsPage), pageType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(false, $"Can't resolve {nameof(IPageService)}");
|
||||
}
|
||||
}
|
||||
|
||||
// TODO WTS: Add tests for functionality you add to MainViewModel.
|
||||
[Fact]
|
||||
public void TestMainViewModelCreation()
|
||||
{
|
||||
var vm = _host.Services.GetService(typeof(MainViewModel));
|
||||
Assert.NotNull(vm);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestGetMainPageType()
|
||||
{
|
||||
if (_host.Services.GetService(typeof(IPageService)) is IPageService pageService)
|
||||
{
|
||||
var pageType = pageService.GetPageType(typeof(MainViewModel).FullName);
|
||||
Assert.Equal(typeof(MainPage), pageType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(false, $"Can't resolve {nameof(IPageService)}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
using System;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Models;
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
using Moq;
|
||||
|
||||
using Xunit;
|
||||
|
||||
namespace ChineseChess.GUI.Tests.XUnit
|
||||
{
|
||||
public class SettingsViewModelTests
|
||||
{
|
||||
public SettingsViewModelTests()
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSettingsViewModel_SetCurrentTheme()
|
||||
{
|
||||
var mockThemeSelectorService = new Mock<IThemeSelectorService>();
|
||||
mockThemeSelectorService.Setup(mock => mock.GetCurrentTheme()).Returns(AppTheme.Light);
|
||||
var mockAppConfig = new Mock<IOptions<AppConfig>>();
|
||||
var mockSystemService = new Mock<ISystemService>();
|
||||
var mockApplicationInfoService = new Mock<IApplicationInfoService>();
|
||||
|
||||
var settingsVm = new SettingsViewModel(mockAppConfig.Object, mockThemeSelectorService.Object, mockSystemService.Object, mockApplicationInfoService.Object);
|
||||
settingsVm.OnNavigatedTo(null);
|
||||
|
||||
Assert.Equal(AppTheme.Light, settingsVm.Theme);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSettingsViewModel_SetCurrentVersion()
|
||||
{
|
||||
var mockThemeSelectorService = new Mock<IThemeSelectorService>();
|
||||
var mockAppConfig = new Mock<IOptions<AppConfig>>();
|
||||
var mockSystemService = new Mock<ISystemService>();
|
||||
var mockApplicationInfoService = new Mock<IApplicationInfoService>();
|
||||
var testVersion = new Version(1, 2, 3, 4);
|
||||
mockApplicationInfoService.Setup(mock => mock.GetVersion()).Returns(testVersion);
|
||||
|
||||
var settingsVm = new SettingsViewModel(mockAppConfig.Object, mockThemeSelectorService.Object, mockSystemService.Object, mockApplicationInfoService.Object);
|
||||
settingsVm.OnNavigatedTo(null);
|
||||
|
||||
Assert.Equal($"ChineseChess.GUI - {testVersion}", settingsVm.VersionDescription);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestSettingsViewModel_SetThemeCommand()
|
||||
{
|
||||
var mockThemeSelectorService = new Mock<IThemeSelectorService>();
|
||||
var mockAppConfig = new Mock<IOptions<AppConfig>>();
|
||||
var mockSystemService = new Mock<ISystemService>();
|
||||
var mockApplicationInfoService = new Mock<IApplicationInfoService>();
|
||||
|
||||
var settingsVm = new SettingsViewModel(mockAppConfig.Object, mockThemeSelectorService.Object, mockSystemService.Object, mockApplicationInfoService.Object);
|
||||
settingsVm.SetThemeCommand.Execute(AppTheme.Light.ToString());
|
||||
|
||||
mockThemeSelectorService.Verify(mock => mock.SetTheme(AppTheme.Light));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using Xunit;
|
||||
|
||||
namespace ChineseChess.GUI.Tests.XUnit
|
||||
{
|
||||
// TODO WTS: Add appropriate unit tests.
|
||||
public class Tests
|
||||
{
|
||||
[Fact]
|
||||
public void TestMethod1()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<Application
|
||||
x:Class="ChineseChess.GUI.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
DispatcherUnhandledException="OnDispatcherUnhandledException"
|
||||
Exit="OnExit"
|
||||
Startup="OnStartup">
|
||||
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="/Styles/_FontSizes.xaml" />
|
||||
<ResourceDictionary Source="/Styles/_Thickness.xaml" />
|
||||
<ResourceDictionary Source="/Styles/MetroWindow.xaml" />
|
||||
<ResourceDictionary Source="/Styles/TextBlock.xaml" />
|
||||
<!--
|
||||
MahApps.Metro resource dictionaries.
|
||||
Learn more about using MahApps.Metro at https://mahapps.com/
|
||||
-->
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
|
||||
<!-- Accent and AppTheme setting -->
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Dark.Blue.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
@ -1,96 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Contracts.Views;
|
||||
using ChineseChess.GUI.Core.Contracts.Services;
|
||||
using ChineseChess.GUI.Core.Services;
|
||||
using ChineseChess.GUI.Models;
|
||||
using ChineseChess.GUI.Services;
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
using ChineseChess.GUI.Views;
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ChineseChess.GUI
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
private IHost _host;
|
||||
|
||||
public T GetService<T>()
|
||||
where T : class
|
||||
=> _host.Services.GetService(typeof(T)) as T;
|
||||
|
||||
public App()
|
||||
{
|
||||
}
|
||||
|
||||
private async void OnStartup(object sender, StartupEventArgs e)
|
||||
{
|
||||
var appLocation = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
|
||||
|
||||
// For more information about .NET generic host see https://docs.microsoft.com/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.0
|
||||
_host = Host.CreateDefaultBuilder(e.Args)
|
||||
.ConfigureAppConfiguration(c =>
|
||||
{
|
||||
c.SetBasePath(appLocation);
|
||||
})
|
||||
.ConfigureServices(ConfigureServices)
|
||||
.Build();
|
||||
|
||||
await _host.StartAsync();
|
||||
}
|
||||
|
||||
private void ConfigureServices(HostBuilderContext context, IServiceCollection services)
|
||||
{
|
||||
// TODO WTS: Register your services, viewmodels and pages here
|
||||
|
||||
// App Host
|
||||
services.AddHostedService<ApplicationHostService>();
|
||||
|
||||
// Activation Handlers
|
||||
|
||||
// Core Services
|
||||
services.AddSingleton<IFileService, FileService>();
|
||||
|
||||
// Services
|
||||
services.AddSingleton<IApplicationInfoService, ApplicationInfoService>();
|
||||
services.AddSingleton<ISystemService, SystemService>();
|
||||
services.AddSingleton<IPersistAndRestoreService, PersistAndRestoreService>();
|
||||
services.AddSingleton<IThemeSelectorService, ThemeSelectorService>();
|
||||
services.AddSingleton<IPageService, PageService>();
|
||||
services.AddSingleton<INavigationService, NavigationService>();
|
||||
|
||||
// Views and ViewModels
|
||||
services.AddTransient<IShellWindow, ShellWindow>();
|
||||
services.AddTransient<ShellViewModel>();
|
||||
|
||||
services.AddTransient<MainViewModel>();
|
||||
services.AddTransient<MainPage>();
|
||||
|
||||
services.AddTransient<SettingsViewModel>();
|
||||
services.AddTransient<SettingsPage>();
|
||||
|
||||
// Configuration
|
||||
services.Configure<AppConfig>(context.Configuration.GetSection(nameof(AppConfig)));
|
||||
}
|
||||
|
||||
private async void OnExit(object sender, ExitEventArgs e)
|
||||
{
|
||||
await _host.StopAsync();
|
||||
_host.Dispose();
|
||||
_host = null;
|
||||
}
|
||||
|
||||
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
|
||||
{
|
||||
// TODO WTS: Please log and handle the exception as appropriate to your scenario
|
||||
// For more info see https://docs.microsoft.com/dotnet/api/system.windows.application.dispatcherunhandledexception?view=netcore-3.0
|
||||
}
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>ChineseChess.GUI</RootNamespace>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MahApps.Metro" Version="2.4.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.14" />
|
||||
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ChineseChess.GUI.Core\ChineseChess.GUI.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>PublicResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="appsettings.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,11 +0,0 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ChineseChess.GUI.Contracts.Activation
|
||||
{
|
||||
public interface IActivationHandler
|
||||
{
|
||||
bool CanHandle();
|
||||
|
||||
Task HandleAsync();
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ChineseChess.GUI.Contracts.Services
|
||||
{
|
||||
public interface IApplicationInfoService
|
||||
{
|
||||
Version GetVersion();
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace ChineseChess.GUI.Contracts.Services
|
||||
{
|
||||
public interface INavigationService
|
||||
{
|
||||
event EventHandler<string> Navigated;
|
||||
|
||||
bool CanGoBack { get; }
|
||||
|
||||
void Initialize(Frame shellFrame);
|
||||
|
||||
bool NavigateTo(string pageKey, object parameter = null, bool clearNavigation = false);
|
||||
|
||||
void GoBack();
|
||||
|
||||
void UnsubscribeNavigation();
|
||||
|
||||
void CleanNavigation();
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace ChineseChess.GUI.Contracts.Services
|
||||
{
|
||||
public interface IPageService
|
||||
{
|
||||
Type GetPageType(string key);
|
||||
|
||||
Page GetPage(string key);
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace ChineseChess.GUI.Contracts.Services
|
||||
{
|
||||
public interface IPersistAndRestoreService
|
||||
{
|
||||
void RestoreData();
|
||||
|
||||
void PersistData();
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace ChineseChess.GUI.Contracts.Services
|
||||
{
|
||||
public interface ISystemService
|
||||
{
|
||||
void OpenInWebBrowser(string url);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
using System;
|
||||
|
||||
using ChineseChess.GUI.Models;
|
||||
|
||||
namespace ChineseChess.GUI.Contracts.Services
|
||||
{
|
||||
public interface IThemeSelectorService
|
||||
{
|
||||
void InitializeTheme();
|
||||
|
||||
void SetTheme(AppTheme theme);
|
||||
|
||||
AppTheme GetCurrentTheme();
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace ChineseChess.GUI.Contracts.ViewModels
|
||||
{
|
||||
public interface INavigationAware
|
||||
{
|
||||
void OnNavigatedTo(object parameter);
|
||||
|
||||
void OnNavigatedFrom();
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace ChineseChess.GUI.Contracts.Views
|
||||
{
|
||||
public interface IShellWindow
|
||||
{
|
||||
Frame GetNavigationFrame();
|
||||
|
||||
void ShowWindow();
|
||||
|
||||
void CloseWindow();
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace ChineseChess.GUI.Converters
|
||||
{
|
||||
public class EnumToBooleanConverter : IValueConverter
|
||||
{
|
||||
public Type EnumType { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (parameter is string enumString)
|
||||
{
|
||||
if (Enum.IsDefined(EnumType, value))
|
||||
{
|
||||
var enumValue = Enum.Parse(EnumType, enumString);
|
||||
|
||||
return enumValue.Equals(value);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (parameter is string enumString)
|
||||
{
|
||||
return Enum.Parse(EnumType, enumString);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
namespace System.Windows.Controls
|
||||
{
|
||||
public static class FrameExtensions
|
||||
{
|
||||
public static object GetDataContext(this Frame frame)
|
||||
{
|
||||
if (frame.Content is FrameworkElement element)
|
||||
{
|
||||
return element.DataContext;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void CleanNavigation(this Frame frame)
|
||||
{
|
||||
while (frame.CanGoBack)
|
||||
{
|
||||
frame.RemoveBackEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
namespace ChineseChess.GUI.Models
|
||||
{
|
||||
public class AppConfig
|
||||
{
|
||||
public string ConfigurationsFolder { get; set; }
|
||||
|
||||
public string AppPropertiesFileName { get; set; }
|
||||
|
||||
public string PrivacyStatement { get; set; }
|
||||
}
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
namespace ChineseChess.GUI.Models
|
||||
{
|
||||
public enum AppTheme
|
||||
{
|
||||
Default,
|
||||
Light,
|
||||
Dark
|
||||
}
|
||||
}
|
197
ChineseChess.GUI/Properties/Resources.Designer.cs
generated
197
ChineseChess.GUI/Properties/Resources.Designer.cs
generated
@ -1,197 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace ChineseChess.GUI.Properties {
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ChineseChess.GUI.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to wts.ItemName.
|
||||
/// </summary>
|
||||
public static string AppDisplayName {
|
||||
get {
|
||||
return ResourceManager.GetString("AppDisplayName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ShellGoBackButton.
|
||||
/// </summary>
|
||||
public static string ShellGoBackButton {
|
||||
get {
|
||||
return ResourceManager.GetString("ShellGoBackButton", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ShellHamburgerButtonName.
|
||||
/// </summary>
|
||||
public static string ShellHamburgerButtonName {
|
||||
get {
|
||||
return ResourceManager.GetString("ShellHamburgerButtonName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Main.
|
||||
/// </summary>
|
||||
public static string MainPageTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("MainPageTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Main.
|
||||
/// </summary>
|
||||
public static string ShellMainPage {
|
||||
get {
|
||||
return ResourceManager.GetString("ShellMainPage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings page placeholder text. Your app description goes here..
|
||||
/// </summary>
|
||||
public static string SettingsPageAboutText {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageAboutText", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to About this application.
|
||||
/// </summary>
|
||||
public static string SettingsPageAboutTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageAboutTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Choose Theme.
|
||||
/// </summary>
|
||||
public static string SettingsPageChooseThemeText {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageChooseThemeText", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Personalization.
|
||||
/// </summary>
|
||||
public static string SettingsPagePersonalizationTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPagePersonalizationTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Privacy Statement.
|
||||
/// </summary>
|
||||
public static string SettingsPagePrivacyStatementText {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPagePrivacyStatementText", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Dark.
|
||||
/// </summary>
|
||||
public static string SettingsPageRadioButtonDarkTheme {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageRadioButtonDarkTheme", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Light.
|
||||
/// </summary>
|
||||
public static string SettingsPageRadioButtonLightTheme {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageRadioButtonLightTheme", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Default.
|
||||
/// </summary>
|
||||
public static string SettingsPageRadioButtonWindowsDefaultTheme {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageRadioButtonWindowsDefaultTheme", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings.
|
||||
/// </summary>
|
||||
public static string SettingsPageTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("SettingsPageTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Settings.
|
||||
/// </summary>
|
||||
public static string ShellSettingsPage {
|
||||
get {
|
||||
return ResourceManager.GetString("ShellSettingsPage", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,147 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="ShellSettingsPage" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="SettingsPageTitle" xml:space="preserve">
|
||||
<value>Settings</value>
|
||||
</data>
|
||||
<data name="SettingsPageAboutText" xml:space="preserve">
|
||||
<value>Settings page placeholder text. Your app description goes here.</value>
|
||||
</data>
|
||||
<data name="SettingsPageAboutTitle" xml:space="preserve">
|
||||
<value>About this application</value>
|
||||
</data>
|
||||
<data name="SettingsPageChooseThemeText" xml:space="preserve">
|
||||
<value>Choose Theme</value>
|
||||
</data>
|
||||
<data name="SettingsPagePersonalizationTitle" xml:space="preserve">
|
||||
<value>Personalization</value>
|
||||
</data>
|
||||
<data name="SettingsPagePrivacyStatementText" xml:space="preserve">
|
||||
<value>Privacy Statement</value>
|
||||
</data>
|
||||
<data name="SettingsPageRadioButtonDarkTheme" xml:space="preserve">
|
||||
<value>Dark</value>
|
||||
</data>
|
||||
<data name="SettingsPageRadioButtonLightTheme" xml:space="preserve">
|
||||
<value>Light</value>
|
||||
</data>
|
||||
<data name="SettingsPageRadioButtonWindowsDefaultTheme" xml:space="preserve">
|
||||
<value>Default</value>
|
||||
</data>
|
||||
<data name="ShellMainPage" xml:space="preserve">
|
||||
<value>Main</value>
|
||||
</data>
|
||||
<data name="MainPageTitle" xml:space="preserve">
|
||||
<value>Main</value>
|
||||
</data>
|
||||
<data name="ShellGoBackButton" xml:space="preserve">
|
||||
<value>Go back</value>
|
||||
</data>
|
||||
<data name="ShellHamburgerButtonName" xml:space="preserve">
|
||||
<value>Open or close navigation</value>
|
||||
</data>
|
||||
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="AppDisplayName" xml:space="preserve">
|
||||
<value>ChineseChess.GUI</value>
|
||||
</data>
|
||||
</root>
|
@ -1,93 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Activation;
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Contracts.Views;
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class ApplicationHostService : IHostedService
|
||||
{
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly INavigationService _navigationService;
|
||||
private readonly IPersistAndRestoreService _persistAndRestoreService;
|
||||
private readonly IThemeSelectorService _themeSelectorService;
|
||||
private readonly IEnumerable<IActivationHandler> _activationHandlers;
|
||||
private IShellWindow _shellWindow;
|
||||
private bool _isInitialized;
|
||||
|
||||
public ApplicationHostService(IServiceProvider serviceProvider, IEnumerable<IActivationHandler> activationHandlers, INavigationService navigationService, IThemeSelectorService themeSelectorService, IPersistAndRestoreService persistAndRestoreService)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
_activationHandlers = activationHandlers;
|
||||
_navigationService = navigationService;
|
||||
_themeSelectorService = themeSelectorService;
|
||||
_persistAndRestoreService = persistAndRestoreService;
|
||||
}
|
||||
|
||||
public async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
// Initialize services that you need before app activation
|
||||
await InitializeAsync();
|
||||
|
||||
await HandleActivationAsync();
|
||||
|
||||
// Tasks after activation
|
||||
await StartupAsync();
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
public async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_persistAndRestoreService.PersistData();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task InitializeAsync()
|
||||
{
|
||||
if (!_isInitialized)
|
||||
{
|
||||
_persistAndRestoreService.RestoreData();
|
||||
_themeSelectorService.InitializeTheme();
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task StartupAsync()
|
||||
{
|
||||
if (!_isInitialized)
|
||||
{
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleActivationAsync()
|
||||
{
|
||||
var activationHandler = _activationHandlers.FirstOrDefault(h => h.CanHandle());
|
||||
|
||||
if (activationHandler != null)
|
||||
{
|
||||
await activationHandler.HandleAsync();
|
||||
}
|
||||
|
||||
await Task.CompletedTask;
|
||||
|
||||
if (App.Current.Windows.OfType<IShellWindow>().Count() == 0)
|
||||
{
|
||||
// Default activation that navigates to the apps default page
|
||||
_shellWindow = _serviceProvider.GetService(typeof(IShellWindow)) as IShellWindow;
|
||||
_navigationService.Initialize(_shellWindow.GetNavigationFrame());
|
||||
_shellWindow.ShowWindow();
|
||||
_navigationService.NavigateTo(typeof(MainViewModel).FullName);
|
||||
await Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class ApplicationInfoService : IApplicationInfoService
|
||||
{
|
||||
public ApplicationInfoService()
|
||||
{
|
||||
}
|
||||
|
||||
public Version GetVersion()
|
||||
{
|
||||
// Set the app version in ChineseChess.GUI > Properties > Package > PackageVersion
|
||||
string assemblyLocation = Assembly.GetExecutingAssembly().Location;
|
||||
var version = FileVersionInfo.GetVersionInfo(assemblyLocation).FileVersion;
|
||||
return new Version(version);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Navigation;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Contracts.ViewModels;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class NavigationService : INavigationService
|
||||
{
|
||||
private readonly IPageService _pageService;
|
||||
private Frame _frame;
|
||||
private object _lastParameterUsed;
|
||||
|
||||
public event EventHandler<string> Navigated;
|
||||
|
||||
public bool CanGoBack => _frame.CanGoBack;
|
||||
|
||||
public NavigationService(IPageService pageService)
|
||||
{
|
||||
_pageService = pageService;
|
||||
}
|
||||
|
||||
public void Initialize(Frame shellFrame)
|
||||
{
|
||||
if (_frame == null)
|
||||
{
|
||||
_frame = shellFrame;
|
||||
_frame.Navigated += OnNavigated;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnsubscribeNavigation()
|
||||
{
|
||||
_frame.Navigated -= OnNavigated;
|
||||
_frame = null;
|
||||
}
|
||||
|
||||
public void GoBack()
|
||||
{
|
||||
if (_frame.CanGoBack)
|
||||
{
|
||||
var vmBeforeNavigation = _frame.GetDataContext();
|
||||
_frame.GoBack();
|
||||
if (vmBeforeNavigation is INavigationAware navigationAware)
|
||||
{
|
||||
navigationAware.OnNavigatedFrom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool NavigateTo(string pageKey, object parameter = null, bool clearNavigation = false)
|
||||
{
|
||||
var pageType = _pageService.GetPageType(pageKey);
|
||||
|
||||
if (_frame.Content?.GetType() != pageType || (parameter != null && !parameter.Equals(_lastParameterUsed)))
|
||||
{
|
||||
_frame.Tag = clearNavigation;
|
||||
var page = _pageService.GetPage(pageKey);
|
||||
var navigated = _frame.Navigate(page, parameter);
|
||||
if (navigated)
|
||||
{
|
||||
_lastParameterUsed = parameter;
|
||||
var dataContext = _frame.GetDataContext();
|
||||
if (dataContext is INavigationAware navigationAware)
|
||||
{
|
||||
navigationAware.OnNavigatedFrom();
|
||||
}
|
||||
}
|
||||
|
||||
return navigated;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CleanNavigation()
|
||||
=> _frame.CleanNavigation();
|
||||
|
||||
private void OnNavigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
if (sender is Frame frame)
|
||||
{
|
||||
bool clearNavigation = (bool)frame.Tag;
|
||||
if (clearNavigation)
|
||||
{
|
||||
frame.CleanNavigation();
|
||||
}
|
||||
|
||||
var dataContext = frame.GetDataContext();
|
||||
if (dataContext is INavigationAware navigationAware)
|
||||
{
|
||||
navigationAware.OnNavigatedTo(e.ExtraData);
|
||||
}
|
||||
|
||||
Navigated?.Invoke(sender, dataContext.GetType().FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
using ChineseChess.GUI.Views;
|
||||
|
||||
using Microsoft.Toolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class PageService : IPageService
|
||||
{
|
||||
private readonly Dictionary<string, Type> _pages = new Dictionary<string, Type>();
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public PageService(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
Configure<MainViewModel, MainPage>();
|
||||
Configure<SettingsViewModel, SettingsPage>();
|
||||
}
|
||||
|
||||
public Type GetPageType(string key)
|
||||
{
|
||||
Type pageType;
|
||||
lock (_pages)
|
||||
{
|
||||
if (!_pages.TryGetValue(key, out pageType))
|
||||
{
|
||||
throw new ArgumentException($"Page not found: {key}. Did you forget to call PageService.Configure?");
|
||||
}
|
||||
}
|
||||
|
||||
return pageType;
|
||||
}
|
||||
|
||||
public Page GetPage(string key)
|
||||
{
|
||||
var pageType = GetPageType(key);
|
||||
return _serviceProvider.GetService(pageType) as Page;
|
||||
}
|
||||
|
||||
private void Configure<VM, V>()
|
||||
where VM : ObservableObject
|
||||
where V : Page
|
||||
{
|
||||
lock (_pages)
|
||||
{
|
||||
var key = typeof(VM).FullName;
|
||||
if (_pages.ContainsKey(key))
|
||||
{
|
||||
throw new ArgumentException($"The key {key} is already configured in PageService");
|
||||
}
|
||||
|
||||
var type = typeof(V);
|
||||
if (_pages.Any(p => p.Value == type))
|
||||
{
|
||||
throw new ArgumentException($"This type is already configured with key {_pages.First(p => p.Value == type).Key}");
|
||||
}
|
||||
|
||||
_pages.Add(key, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Core.Contracts.Services;
|
||||
using ChineseChess.GUI.Models;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class PersistAndRestoreService : IPersistAndRestoreService
|
||||
{
|
||||
private readonly IFileService _fileService;
|
||||
private readonly AppConfig _appConfig;
|
||||
private readonly string _localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||
|
||||
public PersistAndRestoreService(IFileService fileService, IOptions<AppConfig> appConfig)
|
||||
{
|
||||
_fileService = fileService;
|
||||
_appConfig = appConfig.Value;
|
||||
}
|
||||
|
||||
public void PersistData()
|
||||
{
|
||||
if (App.Current.Properties != null)
|
||||
{
|
||||
var folderPath = Path.Combine(_localAppData, _appConfig.ConfigurationsFolder);
|
||||
var fileName = _appConfig.AppPropertiesFileName;
|
||||
_fileService.Save(folderPath, fileName, App.Current.Properties);
|
||||
}
|
||||
}
|
||||
|
||||
public void RestoreData()
|
||||
{
|
||||
var folderPath = Path.Combine(_localAppData, _appConfig.ConfigurationsFolder);
|
||||
var fileName = _appConfig.AppPropertiesFileName;
|
||||
var properties = _fileService.Read<IDictionary>(folderPath, fileName);
|
||||
if (properties != null)
|
||||
{
|
||||
foreach (DictionaryEntry property in properties)
|
||||
{
|
||||
App.Current.Properties.Add(property.Key, property.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class SystemService : ISystemService
|
||||
{
|
||||
public SystemService()
|
||||
{
|
||||
}
|
||||
|
||||
public void OpenInWebBrowser(string url)
|
||||
{
|
||||
// For more info see https://github.com/dotnet/corefx/issues/10361
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = url,
|
||||
UseShellExecute = true
|
||||
};
|
||||
Process.Start(psi);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
using System;
|
||||
using System.Windows;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Models;
|
||||
|
||||
using ControlzEx.Theming;
|
||||
|
||||
using MahApps.Metro.Theming;
|
||||
|
||||
namespace ChineseChess.GUI.Services
|
||||
{
|
||||
public class ThemeSelectorService : IThemeSelectorService
|
||||
{
|
||||
private const string HcDarkTheme = "pack://application:,,,/Styles/Themes/HC.Dark.Blue.xaml";
|
||||
private const string HcLightTheme = "pack://application:,,,/Styles/Themes/HC.Light.Blue.xaml";
|
||||
|
||||
public ThemeSelectorService()
|
||||
{
|
||||
}
|
||||
|
||||
public void InitializeTheme()
|
||||
{
|
||||
// TODO WTS: Mahapps.Metro supports syncronization with high contrast but you have to provide custom high contrast themes
|
||||
// We've added basic high contrast dictionaries for Dark and Light themes
|
||||
// Please complete these themes following the docs on https://mahapps.com/docs/themes/thememanager#creating-custom-themes
|
||||
ThemeManager.Current.AddLibraryTheme(new LibraryTheme(new Uri(HcDarkTheme), MahAppsLibraryThemeProvider.DefaultInstance));
|
||||
ThemeManager.Current.AddLibraryTheme(new LibraryTheme(new Uri(HcLightTheme), MahAppsLibraryThemeProvider.DefaultInstance));
|
||||
|
||||
var theme = GetCurrentTheme();
|
||||
SetTheme(theme);
|
||||
}
|
||||
|
||||
public void SetTheme(AppTheme theme)
|
||||
{
|
||||
if (theme == AppTheme.Default)
|
||||
{
|
||||
ThemeManager.Current.ThemeSyncMode = ThemeSyncMode.SyncAll;
|
||||
ThemeManager.Current.SyncTheme();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThemeManager.Current.ThemeSyncMode = ThemeSyncMode.SyncWithHighContrast;
|
||||
ThemeManager.Current.SyncTheme();
|
||||
ThemeManager.Current.ChangeTheme(Application.Current, $"{theme}.Blue", SystemParameters.HighContrast);
|
||||
}
|
||||
|
||||
App.Current.Properties["Theme"] = theme.ToString();
|
||||
}
|
||||
|
||||
public AppTheme GetCurrentTheme()
|
||||
{
|
||||
if (App.Current.Properties.Contains("Theme"))
|
||||
{
|
||||
var themeName = App.Current.Properties["Theme"].ToString();
|
||||
Enum.TryParse(themeName, out AppTheme theme);
|
||||
return theme;
|
||||
}
|
||||
|
||||
return AppTheme.Default;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls">
|
||||
|
||||
<Style
|
||||
x:Key="CustomMetroWindow"
|
||||
TargetType="{x:Type controls:MetroWindow}"
|
||||
BasedOn="{StaticResource {x:Type controls:MetroWindow}}">
|
||||
<Setter Property="ShowTitleBar" Value="True" />
|
||||
<Setter Property="Height" Value="450" />
|
||||
<Setter Property="Width" Value="800" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
@ -1,54 +0,0 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!--Base Styles-->
|
||||
<Style x:Key="BaseTextBlockStyle" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="FontSize" Value="{StaticResource MediumFontSize}" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="BaseIconStyle" TargetType="{x:Type TextBlock}">
|
||||
<Setter Property="FontFamily" Value="Segoe MDL2 Assets" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="TextAlignment" Value="Center" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="PageTitleStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
|
||||
<Setter Property="FontSize" Value="{StaticResource XLargeFontSize}" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Margin" Value="{StaticResource MediumLeftMargin}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SubtitleTextStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="FontSize" Value="{StaticResource LargeFontSize}" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="BodyTextStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ListTitleStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
|
||||
<Setter Property="TextWrapping" Value="NoWrap" />
|
||||
<Setter Property="FontWeight" Value="Bold" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="ListSubTitleStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseTextBlockStyle}">
|
||||
<Setter Property="TextWrapping" Value="NoWrap" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="SmallIconStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseIconStyle}">
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MediumIconStyle" TargetType="{x:Type TextBlock}" BasedOn="{StaticResource BaseIconStyle}">
|
||||
<Setter Property="FontSize" Value="24" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="BigIconStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseIconStyle}">
|
||||
<Setter Property="FontSize" Value="48" />
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
@ -1,40 +0,0 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:markup="clr-namespace:MahApps.Metro.Markup;assembly=MahApps.Metro"
|
||||
xmlns:markupWithAssembly="clr-namespace:MahApps.Metro.Markup;assembly=MahApps.Metro"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:options="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
|
||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||
mc:Ignorable="options">
|
||||
|
||||
<!-- Metadata -->
|
||||
<system:String x:Key="Theme.Name">Dark.Blue</system:String>
|
||||
<system:String x:Key="Theme.Origin">ChineseChess.GUI</system:String>
|
||||
<system:String x:Key="Theme.DisplayName">Blue (Dark)</system:String>
|
||||
<system:String x:Key="Theme.BaseColorScheme">Dark</system:String>
|
||||
<system:String x:Key="Theme.ColorScheme">Blue</system:String>
|
||||
<system:Boolean x:Key="Theme.IsHighContrast">true</system:Boolean>
|
||||
<Color x:Key="Theme.PrimaryAccentColor">#FF0078D7</Color>
|
||||
<SolidColorBrush x:Key="Theme.ShowcaseBrush" Color="#FF0078D7" options:Freeze="True" />
|
||||
|
||||
<!--
|
||||
We've defined the most basic colors and brushes.
|
||||
Please add other colors and brushes you use in your application. You should have a look at
|
||||
https://github.com/MahApps/MahApps.Metro/blob/develop/src/MahApps.Metro/Styles/Themes/Theme.Template.xaml
|
||||
for a complete reference of all available theme resources.
|
||||
-->
|
||||
|
||||
<!-- *************COLORS START************* -->
|
||||
|
||||
<Color x:Key="MahApps.Colors.ThemeForeground">#FFFFFFFF</Color>
|
||||
<Color x:Key="MahApps.Colors.ThemeBackground">#FF000000</Color>
|
||||
<Color x:Key="MahApps.Colors.IdealForeground">#FFFFFFFF</Color>
|
||||
|
||||
<!-- *************BRUSHES START************* -->
|
||||
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.ThemeBackground" Color="{StaticResource MahApps.Colors.ThemeBackground}" options:Freeze="True" />
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.ThemeForeground" Color="{StaticResource MahApps.Colors.ThemeForeground}" options:Freeze="True" />
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.Text" Color="{StaticResource MahApps.Colors.ThemeForeground}" options:Freeze="True" />
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.IdealForeground" Color="{StaticResource MahApps.Colors.IdealForeground}" options:Freeze="True" />
|
||||
|
||||
</ResourceDictionary>
|
@ -1,40 +0,0 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:markup="clr-namespace:MahApps.Metro.Markup;assembly=MahApps.Metro"
|
||||
xmlns:markupWithAssembly="clr-namespace:MahApps.Metro.Markup;assembly=MahApps.Metro"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:options="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
|
||||
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||
mc:Ignorable="options">
|
||||
|
||||
<!-- Metadata -->
|
||||
<system:String x:Key="Theme.Name">Light.Blue</system:String>
|
||||
<system:String x:Key="Theme.Origin">ChineseChess.GUI</system:String>
|
||||
<system:String x:Key="Theme.DisplayName">Blue (Light)</system:String>
|
||||
<system:String x:Key="Theme.BaseColorScheme">Light</system:String>
|
||||
<system:String x:Key="Theme.ColorScheme">Blue</system:String>
|
||||
<system:Boolean x:Key="Theme.IsHighContrast">true</system:Boolean>
|
||||
<Color x:Key="Theme.PrimaryAccentColor">#FF0078D7</Color>
|
||||
<SolidColorBrush x:Key="Theme.ShowcaseBrush" Color="#FF0078D7" options:Freeze="True" />
|
||||
|
||||
<!--
|
||||
We've defined the most basic colors and brushes.
|
||||
Please add other colors and brushes you use in your application. You should have a look at
|
||||
https://github.com/MahApps/MahApps.Metro/blob/develop/src/MahApps.Metro/Styles/Themes/Theme.Template.xaml
|
||||
for a complete reference of all available theme resources.
|
||||
-->
|
||||
|
||||
<!-- *************COLORS START************* -->
|
||||
|
||||
<Color x:Key="MahApps.Colors.ThemeForeground">#FF000000</Color>
|
||||
<Color x:Key="MahApps.Colors.ThemeBackground">#FFFFFFFF</Color>
|
||||
<Color x:Key="MahApps.Colors.IdealForeground">#FF000000</Color>
|
||||
|
||||
<!-- *************BRUSHES START************* -->
|
||||
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.ThemeBackground" Color="{StaticResource MahApps.Colors.ThemeBackground}" options:Freeze="True" />
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.ThemeForeground" Color="{StaticResource MahApps.Colors.ThemeForeground}" options:Freeze="True" />
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.Text" Color="{StaticResource MahApps.Colors.ThemeForeground}" options:Freeze="True" />
|
||||
<SolidColorBrush x:Key="MahApps.Brushes.IdealForeground" Color="{StaticResource MahApps.Colors.IdealForeground}" options:Freeze="True" />
|
||||
|
||||
</ResourceDictionary>
|
@ -1,14 +0,0 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:sys="clr-namespace:System;assembly=System.Runtime">
|
||||
|
||||
<sys:Double x:Key="SmallFontSize">12</sys:Double>
|
||||
|
||||
<sys:Double x:Key="MediumFontSize">14</sys:Double>
|
||||
|
||||
<sys:Double x:Key="LargeFontSize">18</sys:Double>
|
||||
|
||||
<sys:Double x:Key="XLargeFontSize">22</sys:Double>
|
||||
|
||||
</ResourceDictionary>
|
@ -1,30 +0,0 @@
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
|
||||
<!--Medium size margins-->
|
||||
<Thickness x:Key="MediumLeftMargin">24,0,0,0</Thickness>
|
||||
<Thickness x:Key="MediumLeftTopRightMargin">24,24,24,0</Thickness>
|
||||
<Thickness x:Key="MediumTopMargin">0,24,0,0</Thickness>
|
||||
<Thickness x:Key="MediumLeftRightMargin">24,0,24,0</Thickness>
|
||||
<Thickness x:Key="MediumBottomMargin">0, 0, 0, 24</Thickness>
|
||||
<Thickness x:Key="MediumLeftTopRightBottomMargin">24,24,24,24</Thickness>
|
||||
|
||||
<!--Small size margins-->
|
||||
<Thickness x:Key="SmallLeftMargin">12, 0, 0, 0</Thickness>
|
||||
<Thickness x:Key="SmallLeftTopMargin">12, 12, 0, 0</Thickness>
|
||||
<Thickness x:Key="SmallLeftRightMargin">12, 0, 12, 0</Thickness>
|
||||
<Thickness x:Key="SmallTopMargin">0, 12, 0, 0</Thickness>
|
||||
<Thickness x:Key="SmallRightMargin">0, 0, 12, 0</Thickness>
|
||||
<Thickness x:Key="SmallTopBottomMargin">0, 12, 0, 12</Thickness>
|
||||
<Thickness x:Key="SmallLeftTopRightBottomMargin">12, 12, 12, 12</Thickness>
|
||||
|
||||
<!--Extra Small size margins-->
|
||||
<Thickness x:Key="XSmallLeftMargin">8, 0, 0, 0</Thickness>
|
||||
<Thickness x:Key="XSmallTopMargin">0, 8, 0, 0</Thickness>
|
||||
<Thickness x:Key="XSmallLeftTopRightBottomMargin">8, 8, 8, 8</Thickness>
|
||||
|
||||
<!--Extra Extra Small size margins-->
|
||||
<Thickness x:Key="XXSmallTopMargin">0, 4, 0, 0</Thickness>
|
||||
|
||||
</ResourceDictionary>
|
@ -1,29 +0,0 @@
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
using MahApps.Metro.Controls;
|
||||
|
||||
namespace ChineseChess.GUI.TemplateSelectors
|
||||
{
|
||||
public class MenuItemTemplateSelector : DataTemplateSelector
|
||||
{
|
||||
public DataTemplate GlyphDataTemplate { get; set; }
|
||||
|
||||
public DataTemplate ImageDataTemplate { get; set; }
|
||||
|
||||
public override DataTemplate SelectTemplate(object item, DependencyObject container)
|
||||
{
|
||||
if (item is HamburgerMenuGlyphItem)
|
||||
{
|
||||
return GlyphDataTemplate;
|
||||
}
|
||||
|
||||
if (item is HamburgerMenuImageItem)
|
||||
{
|
||||
return ImageDataTemplate;
|
||||
}
|
||||
|
||||
return base.SelectTemplate(item, container);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
using System;
|
||||
|
||||
using Microsoft.Toolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Toolkit.Mvvm.Input;
|
||||
|
||||
namespace ChineseChess.GUI.ViewModels
|
||||
{
|
||||
public class MainViewModel : ObservableObject
|
||||
{
|
||||
public MainViewModel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using System.Windows.Input;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Contracts.ViewModels;
|
||||
using ChineseChess.GUI.Models;
|
||||
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Toolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Toolkit.Mvvm.Input;
|
||||
|
||||
namespace ChineseChess.GUI.ViewModels
|
||||
{
|
||||
// TODO WTS: Change the URL for your privacy policy in the appsettings.json file, currently set to https://YourPrivacyUrlGoesHere
|
||||
public class SettingsViewModel : ObservableObject, INavigationAware
|
||||
{
|
||||
private readonly AppConfig _appConfig;
|
||||
private readonly IThemeSelectorService _themeSelectorService;
|
||||
private readonly ISystemService _systemService;
|
||||
private readonly IApplicationInfoService _applicationInfoService;
|
||||
private AppTheme _theme;
|
||||
private string _versionDescription;
|
||||
private ICommand _setThemeCommand;
|
||||
private ICommand _privacyStatementCommand;
|
||||
|
||||
public AppTheme Theme
|
||||
{
|
||||
get { return _theme; }
|
||||
set { SetProperty(ref _theme, value); }
|
||||
}
|
||||
|
||||
public string VersionDescription
|
||||
{
|
||||
get { return _versionDescription; }
|
||||
set { SetProperty(ref _versionDescription, value); }
|
||||
}
|
||||
|
||||
public ICommand SetThemeCommand => _setThemeCommand ??= new RelayCommand<string>(OnSetTheme);
|
||||
|
||||
public ICommand PrivacyStatementCommand => _privacyStatementCommand ??= new RelayCommand(OnPrivacyStatement);
|
||||
|
||||
public SettingsViewModel(IOptions<AppConfig> appConfig, IThemeSelectorService themeSelectorService, ISystemService systemService, IApplicationInfoService applicationInfoService)
|
||||
{
|
||||
_appConfig = appConfig.Value;
|
||||
_themeSelectorService = themeSelectorService;
|
||||
_systemService = systemService;
|
||||
_applicationInfoService = applicationInfoService;
|
||||
}
|
||||
|
||||
public void OnNavigatedTo(object parameter)
|
||||
{
|
||||
VersionDescription = $"{Properties.Resources.AppDisplayName} - {_applicationInfoService.GetVersion()}";
|
||||
Theme = _themeSelectorService.GetCurrentTheme();
|
||||
}
|
||||
|
||||
public void OnNavigatedFrom()
|
||||
{
|
||||
}
|
||||
|
||||
private void OnSetTheme(string themeName)
|
||||
{
|
||||
var theme = (AppTheme)Enum.Parse(typeof(AppTheme), themeName);
|
||||
_themeSelectorService.SetTheme(theme);
|
||||
}
|
||||
|
||||
private void OnPrivacyStatement()
|
||||
=> _systemService.OpenInWebBrowser(_appConfig.PrivacyStatement);
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows.Input;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Services;
|
||||
using ChineseChess.GUI.Properties;
|
||||
|
||||
using MahApps.Metro.Controls;
|
||||
|
||||
using Microsoft.Toolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.Toolkit.Mvvm.Input;
|
||||
|
||||
namespace ChineseChess.GUI.ViewModels
|
||||
{
|
||||
public class ShellViewModel : ObservableObject
|
||||
{
|
||||
private readonly INavigationService _navigationService;
|
||||
private HamburgerMenuItem _selectedMenuItem;
|
||||
private HamburgerMenuItem _selectedOptionsMenuItem;
|
||||
private RelayCommand _goBackCommand;
|
||||
private ICommand _menuItemInvokedCommand;
|
||||
private ICommand _optionsMenuItemInvokedCommand;
|
||||
private ICommand _loadedCommand;
|
||||
private ICommand _unloadedCommand;
|
||||
|
||||
public HamburgerMenuItem SelectedMenuItem
|
||||
{
|
||||
get { return _selectedMenuItem; }
|
||||
set { SetProperty(ref _selectedMenuItem, value); }
|
||||
}
|
||||
|
||||
public HamburgerMenuItem SelectedOptionsMenuItem
|
||||
{
|
||||
get { return _selectedOptionsMenuItem; }
|
||||
set { SetProperty(ref _selectedOptionsMenuItem, value); }
|
||||
}
|
||||
|
||||
// TODO WTS: Change the icons and titles for all HamburgerMenuItems here.
|
||||
public ObservableCollection<HamburgerMenuItem> MenuItems { get; } = new ObservableCollection<HamburgerMenuItem>()
|
||||
{
|
||||
new HamburgerMenuGlyphItem() { Label = Resources.ShellMainPage, Glyph = "\uE8A5", TargetPageType = typeof(MainViewModel) },
|
||||
};
|
||||
|
||||
public ObservableCollection<HamburgerMenuItem> OptionMenuItems { get; } = new ObservableCollection<HamburgerMenuItem>()
|
||||
{
|
||||
new HamburgerMenuGlyphItem() { Label = Resources.ShellSettingsPage, Glyph = "\uE713", TargetPageType = typeof(SettingsViewModel) }
|
||||
};
|
||||
|
||||
public RelayCommand GoBackCommand => _goBackCommand ??= new RelayCommand(OnGoBack, CanGoBack);
|
||||
|
||||
public ICommand MenuItemInvokedCommand => _menuItemInvokedCommand ??= new RelayCommand(OnMenuItemInvoked);
|
||||
|
||||
public ICommand OptionsMenuItemInvokedCommand => _optionsMenuItemInvokedCommand ??= new RelayCommand(OnOptionsMenuItemInvoked);
|
||||
|
||||
public ICommand LoadedCommand => _loadedCommand ??= new RelayCommand(OnLoaded);
|
||||
|
||||
public ICommand UnloadedCommand => _unloadedCommand ??= new RelayCommand(OnUnloaded);
|
||||
|
||||
public ShellViewModel(INavigationService navigationService)
|
||||
{
|
||||
_navigationService = navigationService;
|
||||
}
|
||||
|
||||
private void OnLoaded()
|
||||
{
|
||||
_navigationService.Navigated += OnNavigated;
|
||||
}
|
||||
|
||||
private void OnUnloaded()
|
||||
{
|
||||
_navigationService.Navigated -= OnNavigated;
|
||||
}
|
||||
|
||||
private bool CanGoBack()
|
||||
=> _navigationService.CanGoBack;
|
||||
|
||||
private void OnGoBack()
|
||||
=> _navigationService.GoBack();
|
||||
|
||||
private void OnMenuItemInvoked()
|
||||
=> NavigateTo(SelectedMenuItem.TargetPageType);
|
||||
|
||||
private void OnOptionsMenuItemInvoked()
|
||||
=> NavigateTo(SelectedOptionsMenuItem.TargetPageType);
|
||||
|
||||
private void NavigateTo(Type targetViewModel)
|
||||
{
|
||||
if (targetViewModel != null)
|
||||
{
|
||||
_navigationService.NavigateTo(targetViewModel.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNavigated(object sender, string viewModelName)
|
||||
{
|
||||
var item = MenuItems
|
||||
.OfType<HamburgerMenuItem>()
|
||||
.FirstOrDefault(i => viewModelName == i.TargetPageType?.FullName);
|
||||
if (item != null)
|
||||
{
|
||||
SelectedMenuItem = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedOptionsMenuItem = OptionMenuItems
|
||||
.OfType<HamburgerMenuItem>()
|
||||
.FirstOrDefault(i => viewModelName == i.TargetPageType?.FullName);
|
||||
}
|
||||
|
||||
GoBackCommand.NotifyCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
<Page
|
||||
x:Class="ChineseChess.GUI.Views.MainPage"
|
||||
Style="{DynamicResource MahApps.Styles.Page}"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:properties="clr-namespace:ChineseChess.GUI.Properties"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Style="{StaticResource PageTitleStyle}"
|
||||
Margin="{StaticResource MediumLeftMargin}"
|
||||
Text="{x:Static properties:Resources.MainPageTitle}" />
|
||||
<Grid
|
||||
Grid.Row="1"
|
||||
Margin="{StaticResource MediumLeftRightMargin}"
|
||||
Background="{DynamicResource MahApps.Brushes.Gray10}">
|
||||
<!--
|
||||
The Mahapps Gray10 color represents where you should place your content.
|
||||
Place your content here.
|
||||
-->
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Page>
|
@ -1,15 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
|
||||
namespace ChineseChess.GUI.Views
|
||||
{
|
||||
public partial class MainPage : Page
|
||||
{
|
||||
public MainPage(MainViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
<Page
|
||||
x:Class="ChineseChess.GUI.Views.SettingsPage"
|
||||
Style="{DynamicResource MahApps.Styles.Page}"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:converters="clr-namespace:ChineseChess.GUI.Converters"
|
||||
xmlns:models="clr-namespace:ChineseChess.GUI.Models"
|
||||
xmlns:properties="clr-namespace:ChineseChess.GUI.Properties"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Page.Resources>
|
||||
<converters:EnumToBooleanConverter x:Key="EnumToBooleanConverter" EnumType="models:AppTheme" />
|
||||
</Page.Resources>
|
||||
<ScrollViewer>
|
||||
<Grid Margin="{StaticResource SmallTopBottomMargin}">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="48" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Style="{StaticResource PageTitleStyle}"
|
||||
Text="{x:Static properties:Resources.SettingsPageTitle}" />
|
||||
<StackPanel
|
||||
x:Name="ContentArea"
|
||||
Grid.Row="1"
|
||||
Margin="{StaticResource MediumLeftRightMargin}">
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Style="{StaticResource SubtitleTextStyle}"
|
||||
Text="{x:Static properties:Resources.SettingsPagePersonalizationTitle}" />
|
||||
<StackPanel Margin="{StaticResource SmallTopBottomMargin}">
|
||||
<TextBlock
|
||||
Style="{StaticResource BodyTextStyle}"
|
||||
Text="{x:Static properties:Resources.SettingsPageChooseThemeText}" />
|
||||
<StackPanel Margin="{StaticResource XSmallTopMargin}">
|
||||
<RadioButton
|
||||
GroupName="AppTheme"
|
||||
Content="{x:Static properties:Resources.SettingsPageRadioButtonLightTheme}"
|
||||
FontSize="{StaticResource MediumFontSize}"
|
||||
IsChecked="{Binding Theme, Mode=OneWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Light}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Checked">
|
||||
<i:InvokeCommandAction Command="{Binding SetThemeCommand}" CommandParameter="Light" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</RadioButton>
|
||||
<RadioButton
|
||||
GroupName="AppTheme"
|
||||
Content="{x:Static properties:Resources.SettingsPageRadioButtonDarkTheme}"
|
||||
Margin="{StaticResource XSmallTopMargin}"
|
||||
FontSize="{StaticResource MediumFontSize}"
|
||||
IsChecked="{Binding Theme, Mode=OneWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Dark}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Checked">
|
||||
<i:InvokeCommandAction Command="{Binding SetThemeCommand}" CommandParameter="Dark" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</RadioButton>
|
||||
<RadioButton
|
||||
GroupName="AppTheme"
|
||||
Content="{x:Static properties:Resources.SettingsPageRadioButtonWindowsDefaultTheme}"
|
||||
FontSize="{StaticResource MediumFontSize}"
|
||||
Margin="{StaticResource XSmallTopMargin}"
|
||||
IsChecked="{Binding Theme, Mode=OneWay, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter=Default}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Checked">
|
||||
<i:InvokeCommandAction Command="{Binding SetThemeCommand}" CommandParameter="Default" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
</RadioButton>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Style="{StaticResource SubtitleTextStyle}"
|
||||
Text="{x:Static properties:Resources.SettingsPageAboutTitle}" />
|
||||
<TextBlock
|
||||
Text="{Binding VersionDescription, Mode=OneWay}"
|
||||
Margin="{StaticResource XSmallTopMargin}"
|
||||
Style="{StaticResource BodyTextStyle}" />
|
||||
<TextBlock
|
||||
Margin="{StaticResource XSmallTopMargin}"
|
||||
Style="{StaticResource BodyTextStyle}"
|
||||
Text="{x:Static properties:Resources.SettingsPageAboutText}" />
|
||||
|
||||
<TextBlock
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
AutomationProperties.Name="{Binding Text, ElementName=settingsPrivacyStatement}">
|
||||
<Hyperlink
|
||||
Command="{Binding PrivacyStatementCommand}"
|
||||
AutomationProperties.Name="{Binding Text, ElementName=settingsPrivacyStatement}">
|
||||
<TextBlock
|
||||
x:Name="settingsPrivacyStatement"
|
||||
Style="{StaticResource BodyTextStyle}"
|
||||
Text="{x:Static properties:Resources.SettingsPagePrivacyStatementText}" />
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Page>
|
@ -1,15 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
|
||||
namespace ChineseChess.GUI.Views
|
||||
{
|
||||
public partial class SettingsPage : Page
|
||||
{
|
||||
public SettingsPage(SettingsViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = viewModel;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<controls:MetroWindow
|
||||
x:Class="ChineseChess.GUI.Views.ShellWindow"
|
||||
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:controls="http://metro.mahapps.com/winfx/xaml/controls"
|
||||
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
|
||||
xmlns:properties="clr-namespace:ChineseChess.GUI.Properties"
|
||||
xmlns:templateSelectors="clr-namespace:ChineseChess.GUI.TemplateSelectors"
|
||||
Style="{StaticResource CustomMetroWindow}"
|
||||
mc:Ignorable="d"
|
||||
MinWidth="500"
|
||||
MinHeight="350"
|
||||
Title="{x:Static properties:Resources.AppDisplayName}">
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="Loaded">
|
||||
<i:InvokeCommandAction Command="{Binding LoadedCommand}" />
|
||||
</i:EventTrigger>
|
||||
<i:EventTrigger EventName="Unloaded">
|
||||
<i:InvokeCommandAction Command="{Binding UnloadedCommand}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
<controls:MetroWindow.LeftWindowCommands>
|
||||
<controls:WindowCommands>
|
||||
<Button
|
||||
Width="{Binding ElementName=hamburgerMenu, Path=CompactPaneLength}"
|
||||
AutomationProperties.Name="{x:Static properties:Resources.ShellGoBackButton}"
|
||||
ToolTip="{x:Static properties:Resources.ShellGoBackButton}"
|
||||
Command="{Binding GoBackCommand}">
|
||||
<TextBlock
|
||||
Text=""
|
||||
FontSize="14"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
AutomationProperties.Name="{x:Static properties:Resources.ShellGoBackButton}" />
|
||||
</Button>
|
||||
</controls:WindowCommands>
|
||||
</controls:MetroWindow.LeftWindowCommands>
|
||||
<controls:MetroWindow.Resources>
|
||||
<templateSelectors:MenuItemTemplateSelector
|
||||
x:Key="MenuItemTemplateSelector">
|
||||
<templateSelectors:MenuItemTemplateSelector.GlyphDataTemplate>
|
||||
<DataTemplate DataType="{x:Type controls:HamburgerMenuGlyphItem}">
|
||||
<Grid Height="48">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="48" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock
|
||||
Grid.Column="0"
|
||||
FontSize="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe MDL2 Assets"
|
||||
Text="{Binding Glyph}"
|
||||
ToolTip="{Binding Label}" />
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="16"
|
||||
Text="{Binding Label}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</templateSelectors:MenuItemTemplateSelector.GlyphDataTemplate>
|
||||
<templateSelectors:MenuItemTemplateSelector.ImageDataTemplate>
|
||||
<DataTemplate DataType="{x:Type controls:HamburgerMenuImageItem}">
|
||||
<Grid Height="48">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="48" />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Ellipse
|
||||
Grid.Column="0"
|
||||
Width="24"
|
||||
Height="24"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
ToolTip="{Binding Label}">
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush ImageSource="{Binding Thumbnail}" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="16"
|
||||
Text="{Binding Label}" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</templateSelectors:MenuItemTemplateSelector.ImageDataTemplate>
|
||||
</templateSelectors:MenuItemTemplateSelector>
|
||||
</controls:MetroWindow.Resources>
|
||||
<controls:MetroWindow.Content>
|
||||
<controls:HamburgerMenu
|
||||
x:Name="hamburgerMenu"
|
||||
HamburgerButtonName="{x:Static properties:Resources.ShellHamburgerButtonName}"
|
||||
IsPaneOpen="False"
|
||||
DisplayMode="CompactInline"
|
||||
ItemsSource="{Binding MenuItems}"
|
||||
SelectedItem="{Binding SelectedMenuItem}"
|
||||
ItemCommand="{Binding MenuItemInvokedCommand}"
|
||||
OptionsItemsSource="{Binding OptionMenuItems}"
|
||||
SelectedOptionsItem="{Binding SelectedOptionsMenuItem}"
|
||||
OptionsItemCommand="{Binding OptionsMenuItemInvokedCommand}"
|
||||
OptionsItemTemplateSelector="{StaticResource MenuItemTemplateSelector}"
|
||||
ItemTemplateSelector="{StaticResource MenuItemTemplateSelector}">
|
||||
<controls:HamburgerMenu.Content>
|
||||
<Frame
|
||||
x:Name="shellFrame"
|
||||
Grid.Row="1"
|
||||
NavigationUIVisibility="Hidden"
|
||||
Focusable="False" />
|
||||
</controls:HamburgerMenu.Content>
|
||||
</controls:HamburgerMenu>
|
||||
</controls:MetroWindow.Content>
|
||||
</controls:MetroWindow>
|
@ -1,27 +0,0 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
using ChineseChess.GUI.Contracts.Views;
|
||||
using ChineseChess.GUI.ViewModels;
|
||||
|
||||
using MahApps.Metro.Controls;
|
||||
|
||||
namespace ChineseChess.GUI.Views
|
||||
{
|
||||
public partial class ShellWindow : MetroWindow, IShellWindow
|
||||
{
|
||||
public ShellWindow(ShellViewModel viewModel)
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = viewModel;
|
||||
}
|
||||
|
||||
public Frame GetNavigationFrame()
|
||||
=> shellFrame;
|
||||
|
||||
public void ShowWindow()
|
||||
=> Show();
|
||||
|
||||
public void CloseWindow()
|
||||
=> Close();
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
<xml
|
||||
xmlns:genTemplate="http://schemas.microsoft.com/appx/developer/windowsTemplateStudio">
|
||||
<genTemplate:Metadata>
|
||||
<genTemplate:Item Name="generator" Value="Windows Template Studio"/>
|
||||
<genTemplate:Item Name="wizardVersion" Version="v3.10.21120.3" />
|
||||
<genTemplate:Item Name="templatesVersion" Version="v3.10.21120.3" />
|
||||
<genTemplate:Item Name="projectType" Value="SplitView" />
|
||||
<genTemplate:Item Name="framework" Value="MVVMToolkit" />
|
||||
<genTemplate:Item Name="platform" Value="Wpf" />
|
||||
</genTemplate:Metadata>
|
||||
</xml>
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="ChineseChess.GUI.app" />
|
||||
<!-- https://docs.microsoft.com/en-us/windows/desktop/sbscs/application-manifests -->
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"AppConfig": {
|
||||
"configurationsFolder": "ChineseChess.GUI\\Configurations",
|
||||
"appPropertiesFileName": "AppProperties.json",
|
||||
"privacyStatement": "https://YourPrivacyUrlGoesHere/"
|
||||
}
|
||||
}
|
@ -5,11 +5,7 @@ VisualStudioVersion = 16.0.31129.286
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChineseChess.Core", "ChineseChess.Core\ChineseChess.Core.csproj", "{6E2FA057-9341-496B-BD68-EC3E4CE3E18A}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChineseChess.GUI", "ChineseChess.GUI\ChineseChess.GUI.csproj", "{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChineseChess.GUI.Core", "ChineseChess.GUI.Core\ChineseChess.GUI.Core.csproj", "{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ChineseChess.GUI.Tests.xUnit", "ChineseChess.GUI.Tests.xUnit\ChineseChess.GUI.Tests.xUnit.csproj", "{649553A0-4005-4383-BBE5-E601198A49A7}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChineseChess", "ChineseChess\ChineseChess.csproj", "{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -33,42 +29,18 @@ Global
|
||||
{6E2FA057-9341-496B-BD68-EC3E4CE3E18A}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6E2FA057-9341-496B-BD68-EC3E4CE3E18A}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6E2FA057-9341-496B-BD68-EC3E4CE3E18A}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0B8FD863-5EBC-48F0-9A7F-9604C1185F0B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{FF15C546-6BA2-4DA8-8BB6-70C4ABB2B8E1}.Release|x86.Build.0 = Release|Any CPU
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Debug|x64.Build.0 = Debug|x64
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Debug|x86.Build.0 = Debug|x86
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Release|x64.ActiveCfg = Release|x64
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Release|x64.Build.0 = Release|x64
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Release|x86.ActiveCfg = Release|x86
|
||||
{649553A0-4005-4383-BBE5-E601198A49A7}.Release|x86.Build.0 = Release|x86
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Release|x64.Build.0 = Release|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{F671D991-AD7D-4FD9-BC57-AE4BE8CD1136}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
9
ChineseChess/ChineseChess.csproj
Normal file
9
ChineseChess/ChineseChess.csproj
Normal file
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
50
ChineseChess/MainForm.Designer.cs
generated
Normal file
50
ChineseChess/MainForm.Designer.cs
generated
Normal file
@ -0,0 +1,50 @@
|
||||
|
||||
namespace ChineseChess
|
||||
{
|
||||
partial class MainForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(784, 561);
|
||||
this.Name = "MainForm";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "象棋";
|
||||
this.Load += new System.EventHandler(this.Form1_Load);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
25
ChineseChess/MainForm.cs
Normal file
25
ChineseChess/MainForm.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ChineseChess
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
{
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Form1_Load(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
60
ChineseChess/MainForm.resx
Normal file
60
ChineseChess/MainForm.resx
Normal file
@ -0,0 +1,60 @@
|
||||
<root>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
23
ChineseChess/Program.cs
Normal file
23
ChineseChess/Program.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ChineseChess
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.SetHighDpiMode(HighDpiMode.SystemAware);
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user