file-scoped namespaces and other cleanup stuff

This commit is contained in:
Holger Börchers 2023-04-02 22:49:00 +02:00
parent c2e7cc1a3c
commit fc7cdceb05
15 changed files with 415 additions and 443 deletions

View File

@ -1,5 +1,3 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
@ -11,100 +9,99 @@ using Avalonia.Themes.Simple;
using AvaloniaCoreRTDemo.Interfaces;
using AvaloniaCoreRTDemo.Windows;
namespace AvaloniaCoreRTDemo
namespace AvaloniaCoreRTDemo;
public sealed class App : Application, IThemeSwitch
{
public sealed class App : Application, IThemeSwitch
private FluentTheme _fluentTheme = default!;
private SimpleTheme _simpleTheme = default!;
private IStyle _fluentDataGrid = default!;
private IStyle _simpleDataGrid = default!;
private ApplicationTheme _currentTheme;
public override void Initialize()
{
private FluentTheme _fluentTheme = default!;
private SimpleTheme _simpleTheme = default!;
private IStyle _fluentDataGrid = default!;
private IStyle _simpleDataGrid = default!;
AvaloniaXamlLoader.Load(this);
Name = "AvaloniaCoreRTDemo";
}
private ApplicationTheme _currentTheme;
public override void Initialize()
public override void OnFrameworkInitializationCompleted()
{
InitializeThemes();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
AvaloniaXamlLoader.Load(this);
Name = "AvaloniaCoreRTDemo";
desktop.MainWindow = new MainWindow();
DataContext = desktop.MainWindow.DataContext;
}
base.OnFrameworkInitializationCompleted();
}
private void InitializeThemes()
{
_simpleTheme = new SimpleTheme();
_fluentTheme = new FluentTheme();
_fluentDataGrid = (IStyle)Resources["fluentDataGrid"]!;
_simpleDataGrid = (IStyle)Resources["simpleDataGrid"]!;
Styles.Add(_fluentTheme);
Styles.Add(_fluentDataGrid);
_currentTheme = ApplicationTheme.FluentLight;
}
ApplicationTheme IThemeSwitch.Current => _currentTheme;
void IThemeSwitch.ChangeTheme(ApplicationTheme theme)
{
if (theme == _currentTheme)
return;
bool themeChanged = theme switch
{
ApplicationTheme.SimpleLight => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight,
ApplicationTheme.SimpleDark => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight,
ApplicationTheme.FluentLight => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark,
ApplicationTheme.FluentDark => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark,
_ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null)
};
_currentTheme = theme;
switch (theme)
{
case ApplicationTheme.SimpleLight:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
Styles[0] = _simpleTheme;
Styles[1] = _simpleDataGrid;
break;
case ApplicationTheme.SimpleDark:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
Styles[0] = _simpleTheme;
Styles[1] = _simpleDataGrid;
break;
case ApplicationTheme.FluentLight:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
Styles[0] = _fluentTheme;
Styles[1] = _fluentDataGrid;
break;
case ApplicationTheme.FluentDark:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
Styles[0] = _fluentTheme;
Styles[1] = _fluentDataGrid;
break;
}
public override void OnFrameworkInitializationCompleted()
if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
InitializeThemes();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
DataContext = desktop.MainWindow.DataContext;
}
base.OnFrameworkInitializationCompleted();
}
MainWindow oldWindow = (desktop.MainWindow as MainWindow)!;
MainWindow newWindow = new MainWindow(oldWindow);
private void InitializeThemes()
{
_simpleTheme = new SimpleTheme();
_fluentTheme = new FluentTheme();
desktop.MainWindow = newWindow;
DataContext = newWindow.DataContext;
_fluentDataGrid = (IStyle)Resources["fluentDataGrid"]!;
_simpleDataGrid = (IStyle)Resources["simpleDataGrid"]!;
Styles.Add(_fluentTheme);
Styles.Add(_fluentDataGrid);
_currentTheme = ApplicationTheme.FluentLight;
}
ApplicationTheme IThemeSwitch.Current => _currentTheme;
void IThemeSwitch.ChangeTheme(ApplicationTheme theme)
{
if (theme == _currentTheme)
return;
bool themeChanged = theme switch
{
ApplicationTheme.SimpleLight => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight,
ApplicationTheme.SimpleDark => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight,
ApplicationTheme.FluentLight => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark,
ApplicationTheme.FluentDark => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark,
_ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null)
};
_currentTheme = theme;
switch (theme)
{
case ApplicationTheme.SimpleLight:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
Styles[0] = _simpleTheme;
Styles[1] = _simpleDataGrid;
break;
case ApplicationTheme.SimpleDark:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
Styles[0] = _simpleTheme;
Styles[1] = _simpleDataGrid;
break;
case ApplicationTheme.FluentLight:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
Styles[0] = _fluentTheme;
Styles[1] = _fluentDataGrid;
break;
case ApplicationTheme.FluentDark:
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
Styles[0] = _fluentTheme;
Styles[1] = _fluentDataGrid;
break;
}
if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
MainWindow oldWindow = (desktop.MainWindow as MainWindow)!;
MainWindow newWindow = new MainWindow(oldWindow);
desktop.MainWindow = newWindow;
DataContext = newWindow.DataContext;
oldWindow.Hide();
newWindow.Show();
oldWindow.Close();
}
oldWindow.Hide();
newWindow.Show();
oldWindow.Close();
}
}
}
}

View File

@ -1,12 +1,9 @@
using System;
namespace AvaloniaCoreRTDemo;
namespace AvaloniaCoreRTDemo
public enum ApplicationTheme : byte
{
public enum ApplicationTheme : byte
{
SimpleLight = 0,
SimpleDark = 1,
FluentLight = 2,
FluentDark = 3,
}
}
SimpleLight = 0,
SimpleDark = 1,
FluentLight = 2,
FluentDark = 3,
}

View File

@ -11,7 +11,7 @@
<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
<SelfContained>true</SelfContained>
<ImplicitUsing>enable</ImplicitUsing>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<PropertyGroup>
@ -61,6 +61,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="PublishAotCompressed" Version="1.0.0" />
</ItemGroup>
<!-- Information for Dotnet.Bundle to Generate macOS app-->

View File

@ -3,24 +3,23 @@ using Avalonia.Markup.Xaml;
using AvaloniaCoreRTDemo.Controls.ViewModels;
namespace AvaloniaCoreRTDemo.Controls
namespace AvaloniaCoreRTDemo.Controls;
public sealed partial class MainControl : UserControl
{
public sealed partial class MainControl : UserControl
public MainControl()
{
public MainControl()
{
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
DataContext = new MainControlViewModel();
}
public void Reload(IMainWindowState model)
{
DataContext = new MainControlViewModel(model);
}
InitializeComponent();
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
DataContext = new MainControlViewModel();
}
public void Reload(IMainWindowState model)
{
DataContext = new MainControlViewModel(model);
}
}

View File

@ -1,46 +1,45 @@
using Avalonia.Media.Imaging;
using MvvmGen;
namespace AvaloniaCoreRTDemo.Controls.ViewModels
namespace AvaloniaCoreRTDemo.Controls.ViewModels;
[ViewModel]
internal sealed partial class MainControlViewModel : IMainWindowState
{
[ViewModel]
internal sealed partial class MainControlViewModel : IMainWindowState
private IBitmap _dotNetImage;
private IBitmap _avaloniaImage;
private bool _unloadable = false;
public IBitmap DotNetImage => _dotNetImage;
public IBitmap AvaloniaImage => _avaloniaImage;
public string? Text { get; set; }
partial void OnInitialize()
{
private IBitmap _dotNetImage;
private IBitmap _avaloniaImage;
_dotNetImage = Utilities.GetImageFromFile("dotnet.png");
_avaloniaImage = Utilities.GetImageFromFile("avalonia.png");
}
private bool _unloadable = false;
public MainControlViewModel(IMainWindowState state) : this()
{
_avaloniaImage = state.AvaloniaImage;
_dotNetImage = state.DotNetImage;
Text = state.Text;
state.SetUnloadable();
}
public IBitmap DotNetImage => _dotNetImage;
public IBitmap AvaloniaImage => _avaloniaImage;
public string? Text { get; set; }
partial void OnInitialize()
~MainControlViewModel()
{
if (!_unloadable)
{
_dotNetImage = Utilities.GetImageFromFile("dotnet.png");
_avaloniaImage = Utilities.GetImageFromFile("avalonia.png");
}
public MainControlViewModel(IMainWindowState state) : this()
{
_avaloniaImage = state.AvaloniaImage;
_dotNetImage = state.DotNetImage;
Text = state.Text;
state.SetUnloadable();
}
~MainControlViewModel()
{
if (!_unloadable)
{
_dotNetImage.Dispose();
_avaloniaImage.Dispose();
}
}
void IMainWindowState.SetUnloadable()
{
_unloadable = true;
_dotNetImage.Dispose();
_avaloniaImage.Dispose();
}
}
}
void IMainWindowState.SetUnloadable()
{
_unloadable = true;
}
}

View File

@ -1,15 +1,14 @@
using Avalonia;
using Avalonia.Controls;
namespace AvaloniaCoreRTDemo.Interfaces
namespace AvaloniaCoreRTDemo.Interfaces;
public interface IMainWindow
{
public interface IMainWindow
{
IThemeSwitch ThemeSwitch { get; }
IMainWindowState Model { get; }
PixelPoint Position { get; }
Size ClientSize { get; }
Size? FrameSize { get; }
WindowState State { get; }
}
}
IThemeSwitch ThemeSwitch { get; }
IMainWindowState Model { get; }
PixelPoint Position { get; }
Size ClientSize { get; }
Size? FrameSize { get; }
WindowState State { get; }
}

View File

@ -1,15 +1,12 @@
using System;
using Avalonia.Media.Imaging;
using Avalonia.Media.Imaging;
namespace AvaloniaCoreRTDemo;
namespace AvaloniaCoreRTDemo
public interface IMainWindowState
{
public interface IMainWindowState
{
IBitmap DotNetImage { get; }
IBitmap AvaloniaImage { get; }
string? Text { get; }
IBitmap DotNetImage { get; }
IBitmap AvaloniaImage { get; }
string? Text { get; }
void SetUnloadable();
}
}
void SetUnloadable();
}

View File

@ -1,8 +1,7 @@
namespace AvaloniaCoreRTDemo.Interfaces
namespace AvaloniaCoreRTDemo.Interfaces;
public interface IThemeSwitch
{
public interface IThemeSwitch
{
ApplicationTheme Current { get; }
void ChangeTheme(ApplicationTheme theme);
}
}
ApplicationTheme Current { get; }
void ChangeTheme(ApplicationTheme theme);
}

View File

@ -1,17 +1,16 @@
using Avalonia;
namespace AvaloniaCoreRTDemo
{
public static class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
namespace AvaloniaCoreRTDemo;
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>().UsePlatformDetect()
public static class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
public static void Main(string[] args) => BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>().UsePlatformDetect()
.LogToTrace();
}
}
}

View File

@ -1,49 +1,46 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace AvaloniaCoreRTDemo
namespace AvaloniaCoreRTDemo;
internal static class Utilities
{
internal static class Utilities
public static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static readonly bool IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
public static Bitmap GetImageFromResources(string fileName)
{
public static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static readonly bool IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
public static Bitmap GetImageFromResources(string fileName)
{
var assetLoader = AvaloniaLocator.Current.GetRequiredService<IAssetLoader>();
using var assetStream = assetLoader.Open(new Uri($"avares://AvaloniaCoreRTDemo/Images/{fileName}"));
return new Bitmap(assetStream);
}
public static PixelPoint GetWindowPosition(Window window)
{
if (!IsOSX || !window.FrameSize.HasValue)
return window.Position;
else
{
int yOffset = (int)(window.FrameSize.Value.Height - window.ClientSize.Height);
return new(window.Position.X, window.Position.Y + yOffset);
}
}
public static Bitmap GetImageFromFile(string path)
{
try
{
return new Bitmap(GetImageFullPath(path));
}
catch (Exception)
{
return GetImageFromResources("broken-link.png");
}
}
private static string GetImageFullPath(string fileName) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
var assetLoader = AvaloniaLocator.Current.GetRequiredService<IAssetLoader>();
using var assetStream = assetLoader.Open(new Uri($"avares://AvaloniaCoreRTDemo/Images/{fileName}"));
return new Bitmap(assetStream);
}
}
public static PixelPoint GetWindowPosition(Window window)
{
if (!IsOSX || !window.FrameSize.HasValue)
return window.Position;
else
{
int yOffset = (int)(window.FrameSize.Value.Height - window.ClientSize.Height);
return new(window.Position.X, window.Position.Y + yOffset);
}
}
public static Bitmap GetImageFromFile(string path)
{
try
{
return new Bitmap(GetImageFullPath(path));
}
catch (Exception)
{
return GetImageFromResources("broken-link.png");
}
}
private static string GetImageFullPath(string fileName) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
}

View File

@ -1,32 +1,29 @@
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using AvaloniaCoreRTDemo.Windows.ViewModels;
namespace AvaloniaCoreRTDemo.Windows
namespace AvaloniaCoreRTDemo.Windows;
public sealed partial class AboutWindow : Window
{
public sealed partial class AboutWindow : Window
private readonly bool _darkTheme;
public AboutWindow() : this(false) { }
public AboutWindow(bool darkTheme)
{
private readonly bool _darkTheme;
public AboutWindow() : this(false) { }
public AboutWindow(bool darkTheme)
{
_darkTheme = darkTheme;
InitializeComponent();
_darkTheme = darkTheme;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
this.AttachDevTools();
#endif
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
DataContext = new AboutViewModel(_darkTheme);
}
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
DataContext = new AboutViewModel(_darkTheme);
}
}

View File

@ -6,44 +6,43 @@ using AvaloniaCoreRTDemo.Controls;
using AvaloniaCoreRTDemo.Interfaces;
using AvaloniaCoreRTDemo.Windows.ViewModels;
namespace AvaloniaCoreRTDemo.Windows
namespace AvaloniaCoreRTDemo.Windows;
public sealed partial class MainWindow : Window, IMainWindow
{
public sealed partial class MainWindow : Window, IMainWindow
private readonly Application? _app = Application.Current;
private MainControl MainController => this.GetControl<MainControl>("MainControl");
public MainWindow() : this(default) { }
public MainWindow(IMainWindow? window)
{
private readonly Application? _app = Application.Current;
private MainControl MainController => this.GetControl<MainControl>("MainControl");
public MainWindow() : this(default) { }
public MainWindow(IMainWindow? window)
{
InitializeComponent(window);
InitializeComponent(window);
#if DEBUG
this.AttachDevTools();
this.AttachDevTools();
#endif
}
}
IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)_app!;
IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainController.DataContext!;
PixelPoint IMainWindow.Position => Utilities.GetWindowPosition(this);
Size IMainWindow.ClientSize => ClientSize;
Size? IMainWindow.FrameSize => FrameSize;
WindowState IMainWindow.State => WindowState;
IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)_app!;
IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainController.DataContext!;
PixelPoint IMainWindow.Position => Utilities.GetWindowPosition(this);
Size IMainWindow.ClientSize => ClientSize;
Size? IMainWindow.FrameSize => FrameSize;
WindowState IMainWindow.State => WindowState;
private void InitializeComponent(IMainWindow? window)
private void InitializeComponent(IMainWindow? window)
{
AvaloniaXamlLoader.Load(this);
DataContext = new MainViewModel<MainWindow>(this);
if (window is not null)
{
AvaloniaXamlLoader.Load(this);
DataContext = new MainViewModel<MainWindow>(this);
if (window is not null)
{
this.MainController.Reload(window.Model);
WindowStartupLocation = WindowStartupLocation.Manual;
WindowState = window.State;
Position = window.Position;
FrameSize = window.FrameSize;
ClientSize = window.ClientSize;
}
this.MainController.Reload(window.Model);
WindowStartupLocation = WindowStartupLocation.Manual;
WindowState = window.State;
Position = window.Position;
FrameSize = window.FrameSize;
ClientSize = window.ClientSize;
}
}
}
}

View File

@ -1,62 +1,59 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices;
using Avalonia.Media.Imaging;
using MvvmGen;
namespace AvaloniaCoreRTDemo.Windows.ViewModels
namespace AvaloniaCoreRTDemo.Windows.ViewModels;
internal record SystemDetail(string Key, string Value);
[ViewModel]
internal sealed partial class AboutViewModel
{
internal record SystemDetail(string Key, string Value);
private readonly IBitmap _computerImage;
private readonly bool _darkTheme;
[ViewModel]
internal sealed partial class AboutViewModel
public IBitmap ComputerImage => _computerImage;
public IReadOnlyList<SystemDetail> SystemDetails { get; } =
new[]
{
new SystemDetail("Number of Cores", Environment.ProcessorCount.ToString()),
new SystemDetail("OS", RuntimeInformation.OSDescription),
new SystemDetail("OS Arch", RuntimeInformation.OSArchitecture.ToString()),
new SystemDetail("OS Version", Environment.OSVersion.ToString()),
new SystemDetail("Computer", Environment.MachineName),
new SystemDetail("User", Environment.UserName),
new SystemDetail("System Path", Environment.SystemDirectory),
new SystemDetail("Current Path", Environment.CurrentDirectory),
new SystemDetail("Process Arch", RuntimeInformation.ProcessArchitecture.ToString()),
new SystemDetail("Runtime Name", RuntimeInformation.FrameworkDescription),
new SystemDetail("Runtime Path", RuntimeEnvironment.GetRuntimeDirectory()),
new SystemDetail("Runtime Version", RuntimeEnvironment.GetSystemVersion()),
new SystemDetail("Framework Version", Environment.Version.ToString()),
};
private string ComputerImageName
{
private readonly IBitmap _computerImage;
private readonly bool _darkTheme;
public IBitmap ComputerImage => _computerImage;
public IReadOnlyList<SystemDetail> SystemDetails { get; } =
new[]
{
new SystemDetail("Number of Cores", Environment.ProcessorCount.ToString()),
new SystemDetail("OS", RuntimeInformation.OSDescription),
new SystemDetail("OS Arch", RuntimeInformation.OSArchitecture.ToString()),
new SystemDetail("OS Version", Environment.OSVersion.ToString()),
new SystemDetail("Computer", Environment.MachineName),
new SystemDetail("User", Environment.UserName),
new SystemDetail("System Path", Environment.SystemDirectory),
new SystemDetail("Current Path", Environment.CurrentDirectory),
new SystemDetail("Process Arch", RuntimeInformation.ProcessArchitecture.ToString()),
new SystemDetail("Runtime Name", RuntimeInformation.FrameworkDescription),
new SystemDetail("Runtime Path", RuntimeEnvironment.GetRuntimeDirectory()),
new SystemDetail("Runtime Version", RuntimeEnvironment.GetSystemVersion()),
new SystemDetail("Framework Version", Environment.Version.ToString()),
};
private string ComputerImageName
get
{
get
{
if (Utilities.IsWindows)
return !_darkTheme ? "windows.png" : "windows_d.png";
else if (Utilities.IsOSX)
return !_darkTheme ? "macos.png" : "macos_d.png";
else
return !_darkTheme ? "linux.png" : "linux_d.png";
}
}
public AboutViewModel(bool darkTheme) : this()
{
_darkTheme = darkTheme;
_computerImage = Utilities.GetImageFromResources(ComputerImageName);
}
~AboutViewModel()
{
_computerImage.Dispose();
if (Utilities.IsWindows)
return !_darkTheme ? "windows.png" : "windows_d.png";
else if (Utilities.IsOSX)
return !_darkTheme ? "macos.png" : "macos_d.png";
else
return !_darkTheme ? "linux.png" : "linux_d.png";
}
}
}
public AboutViewModel(bool darkTheme) : this()
{
_darkTheme = darkTheme;
_computerImage = Utilities.GetImageFromResources(ComputerImageName);
}
~AboutViewModel()
{
_computerImage.Dispose();
}
}

View File

@ -1,90 +1,87 @@
using System;
using Avalonia.Controls;
using Avalonia.Controls;
using AvaloniaCoreRTDemo.Interfaces;
using MvvmGen;
namespace AvaloniaCoreRTDemo.Windows.ViewModels
namespace AvaloniaCoreRTDemo.Windows.ViewModels;
[ViewModel]
internal abstract partial class ApplicationModelBase
{
[ViewModel]
internal abstract partial class ApplicationModelBase
private readonly IThemeSwitch _themeSwitch;
[Property]
private bool _aboutEnabled = true;
[Property]
private bool _defaultLightEnabled = false;
[Property]
private bool _defaultDarkEnabled = false;
[Property]
private bool _fluentLightEnabled = false;
[Property]
private bool _fluentDarkEnabled = false;
public ApplicationModelBase(IThemeSwitch themeSwitch) : this()
{
private readonly IThemeSwitch _themeSwitch;
[Property]
private bool _aboutEnabled = true;
[Property]
private bool _defaultLightEnabled = false;
[Property]
private bool _defaultDarkEnabled = false;
[Property]
private bool _fluentLightEnabled = false;
[Property]
private bool _fluentDarkEnabled = false;
public ApplicationModelBase(IThemeSwitch themeSwitch) : this()
{
_themeSwitch = themeSwitch;
IntializeTheme(themeSwitch.Current);
}
[Command]
protected abstract void HelpAbout();
[Command]
protected abstract void DefaultLight();
[Command]
protected abstract void DefaultDark();
[Command]
protected abstract void FluentLight();
[Command]
protected abstract void FluentDark();
protected async void RunHelpAbout(Window currentWindow)
{
if (AboutEnabled)
try
{
AboutEnabled = false;
await new AboutWindow(IsDarkTheme(_themeSwitch.Current)).ShowDialog(currentWindow);
}
finally
{
AboutEnabled = true;
}
}
protected void SetTheme(ApplicationTheme theme)
{
IntializeTheme(theme);
_themeSwitch.ChangeTheme(theme);
}
[Command]
private void FileExit() => Environment.Exit(0);
private void IntializeTheme(ApplicationTheme theme)
{
DefaultLightEnabled = theme != ApplicationTheme.SimpleLight;
DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark;
FluentLightEnabled = theme != ApplicationTheme.FluentLight;
FluentDarkEnabled = theme != ApplicationTheme.FluentDark;
}
private static bool IsDarkTheme(ApplicationTheme? theme) =>
theme switch
{
ApplicationTheme.SimpleDark => true,
ApplicationTheme.FluentDark => true,
_ => false,
};
_themeSwitch = themeSwitch;
IntializeTheme(themeSwitch.Current);
}
}
[Command]
protected abstract void HelpAbout();
[Command]
protected abstract void DefaultLight();
[Command]
protected abstract void DefaultDark();
[Command]
protected abstract void FluentLight();
[Command]
protected abstract void FluentDark();
protected async void RunHelpAbout(Window currentWindow)
{
if (AboutEnabled)
try
{
AboutEnabled = false;
await new AboutWindow(IsDarkTheme(_themeSwitch.Current)).ShowDialog(currentWindow);
}
finally
{
AboutEnabled = true;
}
}
protected void SetTheme(ApplicationTheme theme)
{
IntializeTheme(theme);
_themeSwitch.ChangeTheme(theme);
}
[Command]
private void FileExit() => Environment.Exit(0);
private void IntializeTheme(ApplicationTheme theme)
{
DefaultLightEnabled = theme != ApplicationTheme.SimpleLight;
DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark;
FluentLightEnabled = theme != ApplicationTheme.FluentLight;
FluentDarkEnabled = theme != ApplicationTheme.FluentDark;
}
private static bool IsDarkTheme(ApplicationTheme? theme) =>
theme switch
{
ApplicationTheme.SimpleDark => true,
ApplicationTheme.FluentDark => true,
_ => false,
};
}

View File

@ -1,27 +1,25 @@
using Avalonia.Controls;
using AvaloniaCoreRTDemo.Interfaces;
using MvvmGen;
namespace AvaloniaCoreRTDemo.Windows.ViewModels
namespace AvaloniaCoreRTDemo.Windows.ViewModels;
internal sealed class MainViewModel<TWindow> : ApplicationModelBase where TWindow : Window, IMainWindow
{
internal sealed class MainViewModel<TWindow> : ApplicationModelBase where TWindow : Window, IMainWindow
private TWindow _window;
public MainViewModel(TWindow window) : base(window.ThemeSwitch)
{
private TWindow _window;
public MainViewModel(TWindow window) : base(window.ThemeSwitch)
{
_window = window;
}
protected override void HelpAbout() => RunHelpAbout(_window);
protected override void DefaultLight() => SetTheme(ApplicationTheme.SimpleLight);
protected override void DefaultDark() => SetTheme(ApplicationTheme.SimpleDark);
protected override void FluentLight() => SetTheme(ApplicationTheme.FluentLight);
protected override void FluentDark() => SetTheme(ApplicationTheme.FluentDark);
_window = window;
}
}
protected override void HelpAbout() => RunHelpAbout(_window);
protected override void DefaultLight() => SetTheme(ApplicationTheme.SimpleLight);
protected override void DefaultDark() => SetTheme(ApplicationTheme.SimpleDark);
protected override void FluentLight() => SetTheme(ApplicationTheme.FluentLight);
protected override void FluentDark() => SetTheme(ApplicationTheme.FluentDark);
}