This commit is contained in:
Holger Börchers 2021-07-26 21:33:36 +02:00
parent d98021a328
commit 48d244ea20
8 changed files with 76 additions and 228 deletions

2
.vscode/launch.json vendored
View File

@ -10,7 +10,7 @@
"request": "launch", "request": "launch",
"preLaunchTask": "build", "preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path. // If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/App/bin/Debug/net5.0-windows10.0.18362.0/ModernWpfPlayground.dll", "program": "${workspaceFolder}/App/bin/Debug/net5.0-windows10.0.18362.0/win-x64/ModernWpfPlayground.dll",
"args": [], "args": [],
"cwd": "${workspaceFolder}", "cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console

View File

@ -1,9 +1,9 @@
<dryIoc:PrismApplication <Application
x:Class="ModernWpfPlayground.App" x:Class="ModernWpfPlayground.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dryIoc="http://prismlibrary.com/" xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:ui="http://schemas.modernwpf.com/2019"> StartupUri="MainWindow.xaml">
<Application.Resources> <Application.Resources>
<ResourceDictionary> <ResourceDictionary>
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
@ -22,4 +22,4 @@
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>
</dryIoc:PrismApplication> </Application>

View File

@ -1,7 +1,6 @@
using System.Windows; using System.Windows;
using ModernWpf; using ModernWpf;
using ModernWpfPlayground.Types; using ModernWpfPlayground.Types;
using Prism.Ioc;
namespace ModernWpfPlayground namespace ModernWpfPlayground
{ {
@ -16,17 +15,5 @@ namespace ModernWpfPlayground
base.OnStartup(e); base.OnStartup(e);
ThemeManager.Current.AccentColor = AccentColors.Green.ToWindowsColor(); ThemeManager.Current.AccentColor = AccentColors.Green.ToWindowsColor();
} }
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.Register<MainWindow>();
containerRegistry.Register<MainWindowViewModel>();
}
protected override Window CreateShell()
{
return Container.Resolve<MainWindow>();
}
} }
} }

View File

@ -7,20 +7,21 @@
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks" xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:local="clr-namespace:ModernWpfPlayground" xmlns:local="clr-namespace:ModernWpfPlayground"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
xmlns:ui="http://schemas.modernwpf.com/2019" xmlns:ui="http://schemas.modernwpf.com/2019"
x:Name="Window" x:Name="Window"
Title="{Binding Title}" Title="{Binding Title}"
Width="{Binding WindowWidth, Mode=TwoWay}" Width="{Binding WindowWidth, Mode=TwoWay}"
Height="{Binding WindowHeight, Mode=TwoWay}" Height="{Binding WindowHeight, Mode=TwoWay}"
d:DataContext="{d:DesignInstance local:MainWindowViewModel}" d:DataContext="{d:DesignInstance local:MainWindowViewModel}"
prism:ViewModelLocator.AutoWireViewModel="True"
ui:ThemeManager.IsThemeAware="True" ui:ThemeManager.IsThemeAware="True"
ui:TitleBar.ExtendViewIntoTitleBar="True" ui:TitleBar.ExtendViewIntoTitleBar="True"
ui:WindowHelper.UseModernWindowStyle="True" ui:WindowHelper.UseModernWindowStyle="True"
TextOptions.TextFormattingMode="Display" TextOptions.TextFormattingMode="Display"
UseLayoutRounding="True" UseLayoutRounding="True"
mc:Ignorable="d"> mc:Ignorable="d">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Window.Resources> <Window.Resources>
<local:PixelsToGridLengthConverter x:Key="PixelsToGridLength" /> <local:PixelsToGridLengthConverter x:Key="PixelsToGridLength" />
</Window.Resources> </Window.Resources>
@ -219,10 +220,8 @@
</ui:SplitView.Pane> </ui:SplitView.Pane>
<!-- Content --> <!-- Content -->
<TabControl> <TabControl>
<TabItem Header="Bolt"> <TabItem ui:ControlHelper.CornerRadius="0" Header="Bolt">
<ScrollViewer ui:ScrollViewerHelper.AutoHideScrollBars="True"> <ScrollViewer ui:ScrollViewerHelper.AutoHideScrollBars="True">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition /> <ColumnDefinition />
@ -246,7 +245,10 @@
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
</TabItem> </TabItem>
<TabItem Header="General" IsSelected="True"> <TabItem
ui:ControlHelper.CornerRadius="0"
Header="General"
IsSelected="True">
<ScrollViewer ui:ScrollViewerHelper.AutoHideScrollBars="True"> <ScrollViewer ui:ScrollViewerHelper.AutoHideScrollBars="True">
<ui:SimpleStackPanel Margin="5" Spacing="10"> <ui:SimpleStackPanel Margin="5" Spacing="10">

View File

@ -1,166 +1,88 @@
using System.Collections.Generic; using ModernWpfPlayground.Types;
using System.IO; using MvvmGen;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input;
using Microsoft.Win32;
using ModernWpfPlayground.MvvmStuff;
using ModernWpfPlayground.Types;
using Prism.Commands;
using YamlDotNet.Serialization;
using static ModernWpf.ThemeManager; using static ModernWpf.ThemeManager;
namespace ModernWpfPlayground namespace ModernWpfPlayground
{ {
// ReSharper disable once ClassNeverInstantiated.Global // ReSharper disable once ClassNeverInstantiated.Global
public class MainWindowViewModel : BaseViewModel [ViewModel]
public partial class MainWindowViewModel
{ {
private const string AppName = "TaBEA 3.0.0"; private const string AppName = "TaBEA 3.0.0";
[Property, PropertyCallMethod(nameof(SetTitle))]
private string? _path; private string? _path;
private string _title = AppName;
private readonly ISerializer _serializer;
private readonly IDeserializer _deserializer;
public MainWindowViewModel() [Property] private string _title = AppName;
[Property, PropertyCallMethod(nameof(BooleanValue_OnChanged))]
private bool _booleanValue = true;
[Property] private Visibility _visibilityEnumTest = Visibility.Visible;
[Property] private double _sliderTest = 100;
[Property] private double _validationTest;
[Property] private string? _welcomeMessage = "Shadow of the empire";
[Property, PropertyCallMethod(nameof(SetTheme))]
private ThemeMode _themeMode = ThemeMode.UseSystemSetting;
[Property, PropertyCallMethod(nameof(SetAccentColor))]
private AccentColors _accentColors = AccentColors.Green;
[Property] private int _windowWidth = 1200;
[Property] private int _windowHeight = 600;
[Property] private bool _isPaneOpen = true;
[Command]
private void ShowNotification()
{ {
ShowDialogCommand = new DelegateCommand(ShowDialog);
CloseCommand = new DelegateCommand(() => Application.Current.Shutdown());
OpenViewModelCommand = new DelegateCommand(LoadViewModel);
SaveViewModelCommand = new DelegateCommand(SaveViewModel);
ResetViewModelCommand = new DelegateCommand(() =>
{
ResetViewModel();
Path = null;
});
_serializer = new SerializerBuilder().Build();
_deserializer = new DeserializerBuilder().Build();
} }
private string? Path [Command]
private void Close()
{ {
get => _path; Application.Current.MainWindow?.Close();
set => SetProperty(ref _path, value,
() => Title = value != null ? $"{System.IO.Path.GetFileName(value)} - {AppName}" : AppName);
} }
public string Title private void SetTitle()
{ {
get => _title; Title = Path != null ? $"{System.IO.Path.GetFileName(Path)} - {AppName}" : AppName;
set => SetProperty(ref _title, value);
} }
public bool BooleanValue private void SetAccentColor() => Current.AccentColor = AccentColors.ToWindowsColor();
{
get => GetProperty(true);
set => SetProperty(value, BooleanValue_OnChanged);
}
public Visibility VisibilityEnumTest
{
get => GetProperty(Visibility.Visible);
set => SetProperty(value);
}
public double SliderTest private void SetTheme() => Current.ApplicationTheme = ThemeMode.ToApplicationTheme();
{
get => GetProperty(100D);
set => SetProperty(value);
}
public double ValidationTest [Command]
{ private async void ShowDialog()
get => GetProperty(0D);
set => SetProperty(value);
}
public ICommand ShowDialogCommand { get; }
public string? WelcomeMessage
{
get => GetProperty("Shadow of the empire");
set => SetProperty(value);
}
public ICommand CloseCommand { get; }
public ICommand OpenViewModelCommand { get; }
public ICommand SaveViewModelCommand { get; }
public ICommand ResetViewModelCommand { get; }
public ThemeMode ThemeMode
{
get => GetProperty(ThemeMode.UseSystemSetting);
set => SetProperty(value, SetTheme);
}
public AccentColors AccentColors
{
get => GetProperty(AccentColors.Green);
set => SetProperty(value, SetAccentColor);
}
private static void SetAccentColor(AccentColors accentColors) => Current.AccentColor = accentColors.ToWindowsColor();
public int WindowWidth
{
get => GetProperty(1200);
set => SetProperty(value);
}
public int WindowHeight
{
get => GetProperty(600);
set => SetProperty(value);
}
public bool IsPaneOpen
{
get => GetProperty(true);
set => SetProperty(value);
}
private static void SetTheme(ThemeMode themeMode) => Current.ApplicationTheme = themeMode.ToApplicationTheme();
private void ShowDialog()
{ {
var dialog = new ContentDialogExample {Message = WelcomeMessage}; var dialog = new ContentDialogExample {Message = WelcomeMessage};
dialog.ShowAsync().Await(completedCallback: x => WelcomeMessage = x.ToString()); var result = await dialog.ShowAsync();
WelcomeMessage = result.ToString();
} }
private void BooleanValue_OnChanged(bool obj) private void BooleanValue_OnChanged()
{ {
VisibilityEnumTest = obj ? Visibility.Visible : Visibility.Collapsed; VisibilityEnumTest = BooleanValue ? Visibility.Visible : Visibility.Collapsed;
} }
[Command]
private void SaveViewModel() private void SaveViewModel()
{ {
var contents = _serializer.Serialize(Values); // var contents = _serializer.Serialize(Values);
if (Path is null) // if (Path is null)
{ // {
var saveFileDialog = new SaveFileDialog {AddExtension = true, DefaultExt = "*.yaml"}; // var saveFileDialog = new SaveFileDialog {AddExtension = true, DefaultExt = "*.yaml"};
var result = saveFileDialog.ShowDialog(Application.Current.MainWindow?.Owner); // var result = saveFileDialog.ShowDialog(Application.Current.MainWindow?.Owner);
if (result != true) return; // if (result != true) return;
Path = saveFileDialog.FileName; // Path = saveFileDialog.FileName;
} // }
//
File.WriteAllText(Path, contents); // File.WriteAllText(Path, contents);
} }
protected override IEnumerable<(string key, object? value)> GetViewModelItems()
{
var openFileDialog = new OpenFileDialog {AddExtension = true, DefaultExt = "*.yaml"};
var result = openFileDialog.ShowDialog(Application.Current.MainWindow?.Owner);
if (result != true) yield break;
var contents = File.ReadAllText(Path = openFileDialog.FileName);
var obj = _deserializer.Deserialize<Dictionary<string, object>>(contents);
foreach (var (key, value) in obj)
{
yield return (key, DeserializationExtension.Convert(value, ObjectAccessor[key].GetType()));
}
}
} }
} }

View File

@ -5,15 +5,19 @@
<TargetFramework>net5.0-windows10.0.18362.0</TargetFramework> <TargetFramework>net5.0-windows10.0.18362.0</TargetFramework>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<PublishSingleFile>true</PublishSingleFile>
<SelfContained>true</SelfContained>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishTrimmed>true</PublishTrimmed>
<PublishReadyToRun>true</PublishReadyToRun>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="FastMember" Version="1.5.0" /> <PackageReference Include="FastMember" Version="1.5.0" />
<PackageReference Include="ModernWpfUI" Version="0.9.3" /> <PackageReference Include="Hardcodet.NotifyIcon.Wpf" Version="1.1.0" />
<PackageReference Include="Prism.DryIoc" Version="8.0.0.1909" /> <PackageReference Include="ModernWpfUI" Version="0.9.4" />
<PackageReference Include="Prism.Wpf" Version="8.0.0.1909" /> <PackageReference Include="MvvmGen" Version="1.1.1" />
<PackageReference Include="YamlDotNet" Version="9.1.1" /> <PackageReference Include="YamlDotNet" Version="11.2.1" />
<PackageReference Include="System.Drawing.Common" Version="5.0.0" />
<PackageReference Include="MahApps.Metro.IconPacks.FontAwesome" Version="4.8.0" /> <PackageReference Include="MahApps.Metro.IconPacks.FontAwesome" Version="4.8.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,67 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using FastMember;
using Prism.Mvvm;
namespace ModernWpfPlayground.MvvmStuff
{
public abstract class BaseViewModel : BindableBase
{
protected BaseViewModel()
{
ObjectAccessor = ObjectAccessor.Create(this);
}
private readonly Dictionary<string, object?> _values = new();
protected readonly ObjectAccessor ObjectAccessor;
private readonly Dictionary<string, object?> _defaultValues = new();
protected IReadOnlyDictionary<string, object?> Values => _values;
protected bool SetProperty<T>(T value, Action<T>? onChanged = null,
[CallerMemberName] string? propertyName = null)
{
if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
if (_values.TryGetValue(propertyName, out var obj) && Equals(value, obj)) return false;
_values[propertyName] = value;
RaisePropertyChanged(propertyName);
onChanged?.Invoke(value);
return true;
}
protected T? GetProperty<T>(T? defaultValue = default, [CallerMemberName] string? propertyName = null)
{
if (propertyName == null) throw new ArgumentNullException(nameof(propertyName));
if (Values.TryGetValue(propertyName, out var obj))
{
return (T) obj!;
}
_defaultValues[propertyName] =defaultValue;
return defaultValue;
}
protected void ResetViewModel()
{
foreach (var (key, value) in _values.ToArray())
{
if (_defaultValues.TryGetValue(key, out var defaultValue) && Equals(value, defaultValue)) continue;
ObjectAccessor[key] = defaultValue;
}
}
protected abstract IEnumerable<(string key, object? value)> GetViewModelItems();
protected void LoadViewModel()
{
ResetViewModel();
foreach (var (key, value) in GetViewModelItems())
{
ObjectAccessor[key] = value;
}
}
}
}

View File

@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="5.0.0" /> <PackageReference Include="System.Drawing.Common" Version="5.0.2" />
</ItemGroup> </ItemGroup>
</Project> </Project>