1. 移除 ChineseChess.GUI 项目

抱歉,这框架用在这上面,真是用镭射炮打苍蝇,又啰嗦又难用。
我觉得WinForm比较适合这项目,就这样了。
2. 新增 ChineseChess 项目,选择WinForm框架,使用.NET 5.0(总要试试)
This commit is contained in:
筱傑 2021-05-31 22:29:05 +08:00
parent 66af740423
commit aba97a033f
58 changed files with 180 additions and 2193 deletions

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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));
}
}
}
}

View File

@ -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.

View File

@ -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>

View File

@ -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)}");
}
}
}
}

View File

@ -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));
}
}
}

View File

@ -1,13 +0,0 @@
using Xunit;
namespace ChineseChess.GUI.Tests.XUnit
{
// TODO WTS: Add appropriate unit tests.
public class Tests
{
[Fact]
public void TestMethod1()
{
}
}
}

View File

@ -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>

View File

@ -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
}
}
}

View File

@ -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>

View File

@ -1,11 +0,0 @@
using System.Threading.Tasks;
namespace ChineseChess.GUI.Contracts.Activation
{
public interface IActivationHandler
{
bool CanHandle();
Task HandleAsync();
}
}

View File

@ -1,9 +0,0 @@
using System;
namespace ChineseChess.GUI.Contracts.Services
{
public interface IApplicationInfoService
{
Version GetVersion();
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -1,9 +0,0 @@
namespace ChineseChess.GUI.Contracts.Services
{
public interface IPersistAndRestoreService
{
void RestoreData();
void PersistData();
}
}

View File

@ -1,7 +0,0 @@
namespace ChineseChess.GUI.Contracts.Services
{
public interface ISystemService
{
void OpenInWebBrowser(string url);
}
}

View File

@ -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();
}
}

View File

@ -1,9 +0,0 @@
namespace ChineseChess.GUI.Contracts.ViewModels
{
public interface INavigationAware
{
void OnNavigatedTo(object parameter);
void OnNavigatedFrom();
}
}

View File

@ -1,13 +0,0 @@
using System.Windows.Controls;
namespace ChineseChess.GUI.Contracts.Views
{
public interface IShellWindow
{
Frame GetNavigationFrame();
void ShowWindow();
void CloseWindow();
}
}

View File

@ -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;
}
}
}

View File

@ -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();
}
}
}
}

View File

@ -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; }
}
}

View File

@ -1,9 +0,0 @@
namespace ChineseChess.GUI.Models
{
public enum AppTheme
{
Default,
Light,
Dark
}
}

View File

@ -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);
}
}
}
}

View File

@ -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>

View File

@ -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;
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}
}
}

View File

@ -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);
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}
}
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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);
}
}
}

View File

@ -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()
{
}
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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>

View File

@ -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;
}
}
}

View File

@ -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="&#xE72B;"
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>

View File

@ -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();
}
}

View File

@ -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>

View File

@ -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>

View File

@ -1,7 +0,0 @@
{
"AppConfig": {
"configurationsFolder": "ChineseChess.GUI\\Configurations",
"appPropertiesFileName": "AppProperties.json",
"privacyStatement": "https://YourPrivacyUrlGoesHere/"
}
}

View File

@ -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

View 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
View 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
View 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)
{
}
}
}

View 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
View 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());
}
}
}