Removed Reactive stuff and do code cleanup

This commit is contained in:
Holger Börchers 2023-04-02 22:44:52 +02:00
parent 2af0df14c9
commit c2e7cc1a3c
16 changed files with 337 additions and 248 deletions

View File

@ -1,13 +1,18 @@
<Application xmlns="https://github.com/avaloniaui"
<Application
x:Class="AvaloniaCoreRTDemo.App"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels1="clr-namespace:AvaloniaCoreRTDemo.Windows.ViewModels"
RequestedThemeVariant="Light"
x:Class="AvaloniaCoreRTDemo.App"
x:CompileBindings="True"
x:DataType="viewModels1:ApplicationModelBase">
x:DataType="viewModels1:ApplicationModelBase"
RequestedThemeVariant="Light">
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="About" Gesture="cmd+b" IsEnabled="{Binding AboutEnabled}" Command="{Binding HelpAboutMethod}"/>
<NativeMenuItem
Command="{Binding HelpAboutCommand}"
Gesture="cmd+b"
Header="About"
IsEnabled="{Binding AboutEnabled}" />
</NativeMenu>
</NativeMenu.Menu>
<Application.Resources>

View File

@ -25,81 +25,81 @@ namespace AvaloniaCoreRTDemo
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
this.Name = "AvaloniaCoreRTDemo";
Name = "AvaloniaCoreRTDemo";
}
public override void OnFrameworkInitializationCompleted()
{
this.InitializeThemes();
InitializeThemes();
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
this.DataContext = desktop.MainWindow.DataContext;
DataContext = desktop.MainWindow.DataContext;
}
base.OnFrameworkInitializationCompleted();
}
private void InitializeThemes()
{
this._simpleTheme = new SimpleTheme();
this._fluentTheme = new FluentTheme();
_simpleTheme = new SimpleTheme();
_fluentTheme = new FluentTheme();
this._fluentDataGrid = (IStyle)this.Resources["fluentDataGrid"]!;
this._simpleDataGrid = (IStyle)this.Resources["simpleDataGrid"]!;
_fluentDataGrid = (IStyle)Resources["fluentDataGrid"]!;
_simpleDataGrid = (IStyle)Resources["simpleDataGrid"]!;
Styles.Add(_fluentTheme);
Styles.Add(_fluentDataGrid);
this._currentTheme = ApplicationTheme.FluentLight;
_currentTheme = ApplicationTheme.FluentLight;
}
ApplicationTheme IThemeSwitch.Current => this._currentTheme;
ApplicationTheme IThemeSwitch.Current => _currentTheme;
void IThemeSwitch.ChangeTheme(ApplicationTheme theme)
{
if (theme == this._currentTheme)
if (theme == _currentTheme)
return;
Boolean themeChanged = theme switch
bool themeChanged = theme switch
{
ApplicationTheme.SimpleLight => this._currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight,
ApplicationTheme.SimpleDark => this._currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight,
ApplicationTheme.FluentLight => this._currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark,
ApplicationTheme.FluentDark => this._currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark,
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)
};
this._currentTheme = theme;
_currentTheme = theme;
switch (theme)
{
case ApplicationTheme.SimpleLight:
this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
this.Styles[0] = this._simpleTheme;
this.Styles[1] = this._simpleDataGrid;
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
Styles[0] = _simpleTheme;
Styles[1] = _simpleDataGrid;
break;
case ApplicationTheme.SimpleDark:
this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
this.Styles[0] = this._simpleTheme;
this.Styles[1] = this._simpleDataGrid;
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
Styles[0] = _simpleTheme;
Styles[1] = _simpleDataGrid;
break;
case ApplicationTheme.FluentLight:
this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
this.Styles[0] = this._fluentTheme;
this.Styles[1] = this._fluentDataGrid;
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light);
Styles[0] = _fluentTheme;
Styles[1] = _fluentDataGrid;
break;
case ApplicationTheme.FluentDark:
this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
this.Styles[0] = this._fluentTheme;
this.Styles[1] = this._fluentDataGrid;
SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark);
Styles[0] = _fluentTheme;
Styles[1] = _fluentDataGrid;
break;
}
if (themeChanged && this.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
MainWindow oldWindow = (desktop.MainWindow as MainWindow)!;
MainWindow newWindow = new MainWindow(oldWindow);
desktop.MainWindow = newWindow;
this.DataContext = newWindow.DataContext;
DataContext = newWindow.DataContext;
oldWindow.Hide();
newWindow.Show();

View File

@ -2,7 +2,7 @@
namespace AvaloniaCoreRTDemo
{
public enum ApplicationTheme : Byte
public enum ApplicationTheme : byte
{
SimpleLight = 0,
SimpleDark = 1,

View File

@ -11,6 +11,7 @@
<PublishAot>true</PublishAot>
<PublishTrimmed>true</PublishTrimmed>
<SelfContained>true</SelfContained>
<ImplicitUsing>enable</ImplicitUsing>
</PropertyGroup>
<PropertyGroup>
@ -50,13 +51,16 @@
<PackageReference Include="Avalonia" Version="11.0.0-*" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-*" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.0-*" />
<PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-*" />
<PackageReference Include="Avalonia.Themes.Simple" Version="11.0.0-*" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-*" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-*" />
<!--Condition below is needed to generate macOS App only.-->
<PackageReference Include="Dotnet.Bundle" Version="0.9.13" Condition="$(RuntimeIdentifier.StartsWith('osx'))" />
<PackageReference Include="MvvmGen.PureCodeGeneration" Version="1.2.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<!-- Information for Dotnet.Bundle to Generate macOS app-->

View File

@ -1,12 +1,44 @@
<UserControl xmlns="https://github.com/avaloniaui" 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"
<UserControl
x:Class="AvaloniaCoreRTDemo.Controls.MainControl"
xmlns="https://github.com/avaloniaui"
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:viewModels="clr-namespace:AvaloniaCoreRTDemo.Controls.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Controls.MainControl"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="viewModels:MainControlViewModel">
<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto,*" Margin="32">
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" TextAlignment="Center" Margin="0,6">Welcome to Avalonia UI + NativeAOT!</TextBlock>
<Image Grid.Row="1" Grid.Column="0" Stretch="None" Source="{Binding DotNetImage}"/>
<Image Grid.Row="1" Grid.Column="1" Stretch="None" Source="{Binding AvaloniaImage}"/>
<TextBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Watermark="Type here" AcceptsReturn="True" TextWrapping="Wrap" Text="{Binding Text}"/>
x:DataType="viewModels:MainControlViewModel"
mc:Ignorable="d">
<Grid
Margin="32"
ColumnDefinitions="*,*"
RowDefinitions="Auto,Auto,*">
<TextBlock
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Margin="0,6"
TextAlignment="Center">
Welcome to Avalonia UI + NativeAOT!
</TextBlock>
<Image
Grid.Row="1"
Grid.Column="0"
Source="{Binding DotNetImage}"
Stretch="None" />
<Image
Grid.Row="1"
Grid.Column="1"
Source="{Binding AvaloniaImage}"
Stretch="None" />
<TextBox
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
AcceptsReturn="True"
Text="{Binding Text}"
TextWrapping="Wrap"
Watermark="Type here" />
</Grid>
</UserControl>

View File

@ -9,18 +9,18 @@ namespace AvaloniaCoreRTDemo.Controls
{
public MainControl()
{
this.InitializeComponent();
InitializeComponent();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
this.DataContext = new MainControlViewModel();
DataContext = new MainControlViewModel();
}
public void Reload(IMainWindowState model)
{
this.DataContext = new MainControlViewModel(model);
DataContext = new MainControlViewModel(model);
}
}
}

View File

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

View File

@ -8,9 +8,8 @@ namespace AvaloniaCoreRTDemo
{
IBitmap DotNetImage { get; }
IBitmap AvaloniaImage { get; }
String? Text { get; }
string? Text { get; }
void SetUnloadable();
}
}

View File

@ -11,10 +11,10 @@ namespace AvaloniaCoreRTDemo
{
internal static class Utilities
{
public static readonly Boolean IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
public static readonly Boolean IsOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
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 Bitmap GetImageFromResources(string fileName)
{
var assetLoader = AvaloniaLocator.Current.GetRequiredService<IAssetLoader>();
using var assetStream = assetLoader.Open(new Uri($"avares://AvaloniaCoreRTDemo/Images/{fileName}"));
@ -27,12 +27,12 @@ namespace AvaloniaCoreRTDemo
return window.Position;
else
{
Int32 yOffset = (Int32)(window.FrameSize.Value.Height - window.ClientSize.Height);
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)
public static Bitmap GetImageFromFile(string path)
{
try
{
@ -44,7 +44,6 @@ namespace AvaloniaCoreRTDemo
}
}
private static String GetImageFullPath(String fileName)
=> Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
private static string GetImageFullPath(string fileName) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
}
}

View File

@ -1,19 +1,49 @@
<Window xmlns="https://github.com/avaloniaui" 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"
<Window
x:Class="AvaloniaCoreRTDemo.Windows.AboutWindow"
xmlns="https://github.com/avaloniaui"
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:viewModels="clr-namespace:AvaloniaCoreRTDemo.Windows.ViewModels"
mc:Ignorable="d" x:Class="AvaloniaCoreRTDemo.Windows.AboutWindow" d:DesignWidth="640" d:DesignHeight="256"
WindowState="Normal" WindowStartupLocation="CenterOwner" Height="256" MaxWidth="840"
SizeToContent="Width"
Title="About"
CanResize="false" ShowInTaskbar="False" Icon="avares://AvaloniaCoreRTDemo/Assets/about.ico"
Height="256"
MaxWidth="840"
d:DesignHeight="256"
d:DesignWidth="640"
x:CompileBindings="True"
x:DataType="viewModels:AboutViewModel">
<Grid VerticalAlignment="Top" HorizontalAlignment="Left" ColumnDefinitions="Auto,*">
<Image Margin="0, 60" Grid.Column="0" Stretch="None" Source="{Binding ComputerImage}" VerticalAlignment="Top" HorizontalAlignment="Left">
</Image>
<DataGrid Grid.Column="1" Items="{Binding SystemDetails}" IsReadOnly="True" CanUserReorderColumns="False" CanUserSortColumns="False" CanUserResizeColumns="False" HeadersVisibility="None">
x:DataType="viewModels:AboutViewModel"
CanResize="false"
Icon="avares://AvaloniaCoreRTDemo/Assets/about.ico"
ShowInTaskbar="False"
SizeToContent="Width"
WindowStartupLocation="CenterOwner"
WindowState="Normal"
mc:Ignorable="d">
<Grid
HorizontalAlignment="Left"
VerticalAlignment="Top"
ColumnDefinitions="Auto,*">
<Image
Grid.Column="0"
Margin="0,60"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Source="{Binding ComputerImage}"
Stretch="None" />
<DataGrid
Grid.Column="1"
CanUserReorderColumns="False"
CanUserResizeColumns="False"
CanUserSortColumns="False"
HeadersVisibility="None"
IsReadOnly="True"
Items="{Binding SystemDetails}">
<DataGrid.Columns>
<DataGridTextColumn Header="Key" Binding="{Binding Key, x:DataType=viewModels:SystemDetail}" FontWeight="Bold" />
<DataGridTextColumn Header="Value" Binding="{Binding Value, x:DataType=viewModels:SystemDetail}" />
<DataGridTextColumn
Binding="{Binding Key, x:DataType=viewModels:SystemDetail}"
FontWeight="Bold"
Header="Key" />
<DataGridTextColumn Binding="{Binding Value, x:DataType=viewModels:SystemDetail}" Header="Value" />
</DataGrid.Columns>
</DataGrid>
</Grid>

View File

@ -10,14 +10,14 @@ namespace AvaloniaCoreRTDemo.Windows
{
public sealed partial class AboutWindow : Window
{
private readonly Boolean _darkTheme;
private readonly bool _darkTheme;
public AboutWindow() : this(false) { }
public AboutWindow(Boolean darkTheme)
public AboutWindow(bool darkTheme)
{
this._darkTheme = darkTheme;
this.InitializeComponent();
_darkTheme = darkTheme;
InitializeComponent();
#if DEBUG
this.AttachDevTools();
#endif
@ -26,7 +26,7 @@ namespace AvaloniaCoreRTDemo.Windows
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
this.DataContext = new AboutViewModel(this._darkTheme);
DataContext = new AboutViewModel(_darkTheme);
}
}
}

View File

@ -1,31 +1,63 @@
<Window xmlns="https://github.com/avaloniaui" 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"
<Window
x:Class="AvaloniaCoreRTDemo.Windows.MainWindow"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:AvaloniaCoreRTDemo.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:viewModels1="clr-namespace:AvaloniaCoreRTDemo.Windows.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Windows.MainWindow"
Width="640" Height="480" WindowStartupLocation="CenterScreen" Title="AvaloniaCoreRTDemo" Icon="avares://AvaloniaCoreRTDemo/Assets/app.ico" MinWidth="400" MinHeight="350"
Title="AvaloniaCoreRTDemo"
Width="640"
Height="480"
MinWidth="400"
MinHeight="350"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="viewModels1:ApplicationModelBase">
x:DataType="viewModels1:ApplicationModelBase"
Icon="avares://AvaloniaCoreRTDemo/Assets/app.ico"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<DockPanel>
<NativeMenuBar DockPanel.Dock="Top" />
<controls:MainControl Name="MainControl"/>
<controls:MainControl Name="MainControl" />
</DockPanel>
<NativeMenu.Menu>
<NativeMenu>
<NativeMenuItem Header="File">
<NativeMenuItem.Menu>
<NativeMenu>
<NativeMenuItem Header="Exit" Gesture="cmd+e" Command="{Binding FileExitCommand}"/>
<NativeMenuItem Header="About" Gesture="cmd+b" IsEnabled="{Binding AboutEnabled}" Command="{Binding HelpAboutMethod}"/>
<NativeMenuItem
Command="{Binding FileExitCommand}"
Gesture="cmd+e"
Header="Exit" />
<NativeMenuItem
Command="{Binding HelpAboutCommand}"
Gesture="cmd+b"
Header="About"
IsEnabled="{Binding AboutEnabled}" />
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem>
<NativeMenuItem Header="Theme">
<NativeMenuItem.Menu>
<NativeMenu>
<NativeMenuItem Header="Default Light" IsEnabled="{Binding DefaultLightEnabled}" Command="{Binding DefaultLightMethod}"/>
<NativeMenuItem Header="Default Dark" IsEnabled="{Binding DefaultDarkEnabled}" Command="{Binding DefaultDarkMethod}"/>
<NativeMenuItem Header="Fluent Light" IsEnabled="{Binding FluentLightEnabled}" Command="{Binding FluentLightMethod}"/>
<NativeMenuItem Header="Fluent Dark" IsEnabled="{Binding FluentDarkEnabled}" Command="{Binding FluentDarkMethod}"/>
<NativeMenuItem
Command="{Binding DefaultLightCommand}"
Header="Default Light"
IsEnabled="{Binding DefaultLightEnabled}" />
<NativeMenuItem
Command="{Binding DefaultDarkCommand}"
Header="Default Dark"
IsEnabled="{Binding DefaultDarkEnabled}" />
<NativeMenuItem
Command="{Binding FluentLightCommand}"
Header="Fluent Light"
IsEnabled="{Binding FluentLightEnabled}" />
<NativeMenuItem
Command="{Binding FluentDarkCommand}"
Header="Fluent Dark"
IsEnabled="{Binding FluentDarkEnabled}" />
</NativeMenu>
</NativeMenuItem.Menu>
</NativeMenuItem>

View File

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

@ -3,22 +3,22 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using Avalonia.Media.Imaging;
using ReactiveUI;
using MvvmGen;
namespace AvaloniaCoreRTDemo.Windows.ViewModels
{
internal record SystemDetail(string Key, string Value);
internal sealed class AboutViewModel : ReactiveObject
[ViewModel]
internal sealed partial class AboutViewModel
{
private readonly IBitmap _computerImage;
private readonly Boolean _darkTheme;
private readonly bool _darkTheme;
public IBitmap ComputerImage => _computerImage;
public IReadOnlyList<SystemDetail> SystemDetails { get; } = new[]
public IReadOnlyList<SystemDetail> SystemDetails { get; } =
new[]
{
new SystemDetail("Number of Cores", Environment.ProcessorCount.ToString()),
new SystemDetail("OS", RuntimeInformation.OSDescription),
@ -35,28 +35,28 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels
new SystemDetail("Framework Version", Environment.Version.ToString()),
};
private String ComputerImageName
private string ComputerImageName
{
get
{
if (Utilities.IsWindows)
return !this._darkTheme ? "windows.png" : "windows_d.png";
return !_darkTheme ? "windows.png" : "windows_d.png";
else if (Utilities.IsOSX)
return !this._darkTheme ? "macos.png" : "macos_d.png";
return !_darkTheme ? "macos.png" : "macos_d.png";
else
return !this._darkTheme ? "linux.png" : "linux_d.png";
return !_darkTheme ? "linux.png" : "linux_d.png";
}
}
public AboutViewModel(Boolean darkTheme)
public AboutViewModel(bool darkTheme) : this()
{
this._darkTheme = darkTheme;
this._computerImage = Utilities.GetImageFromResources(this.ComputerImageName);
_darkTheme = darkTheme;
_computerImage = Utilities.GetImageFromResources(ComputerImageName);
}
~AboutViewModel()
{
this._computerImage.Dispose();
_computerImage.Dispose();
}
}
}

View File

@ -1,100 +1,86 @@
using System;
using System.Reactive;
using Avalonia.Controls;
using AvaloniaCoreRTDemo.Interfaces;
using ReactiveUI;
using MvvmGen;
namespace AvaloniaCoreRTDemo.Windows.ViewModels
{
internal abstract class ApplicationModelBase : ReactiveObject
[ViewModel]
internal abstract partial class ApplicationModelBase
{
private readonly IThemeSwitch _themeSwitch;
private Boolean _aboutEnable = true;
private Boolean _defaultLightEnable = false;
private Boolean _defaultDarkEnable = false;
private Boolean _fluentLightEnable = false;
private Boolean _fluentDarkEnable = false;
public Boolean AboutEnabled
[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()
{
get => this._aboutEnable;
set => this.RaiseAndSetIfChanged(ref this._aboutEnable, value);
_themeSwitch = themeSwitch;
IntializeTheme(themeSwitch.Current);
}
public Boolean DefaultLightEnabled
{
get => this._defaultLightEnable;
set => this.RaiseAndSetIfChanged(ref this._defaultLightEnable, value);
}
[Command]
protected abstract void HelpAbout();
public Boolean DefaultDarkEnabled
{
get => this._defaultDarkEnable;
set => this.RaiseAndSetIfChanged(ref this._defaultDarkEnable, value);
}
[Command]
protected abstract void DefaultLight();
public Boolean FluentLightEnabled
{
get => this._fluentLightEnable;
set => this.RaiseAndSetIfChanged(ref this._fluentLightEnable, value);
}
[Command]
protected abstract void DefaultDark();
public Boolean FluentDarkEnabled
{
get => this._fluentDarkEnable;
set => this.RaiseAndSetIfChanged(ref this._fluentDarkEnable, value);
}
[Command]
protected abstract void FluentLight();
public ReactiveCommand<Unit, Unit> FileExitCommand { get; }
public ApplicationModelBase(IThemeSwitch themeSwitch)
{
this._themeSwitch = themeSwitch;
this.IntializeTheme(themeSwitch.Current);
this.FileExitCommand = ReactiveCommand.Create(RunFileExit);
}
public abstract void HelpAboutMethod();
public abstract void DefaultLightMethod();
public abstract void DefaultDarkMethod();
public abstract void FluentLightMethod();
public abstract void FluentDarkMethod();
[Command]
protected abstract void FluentDark();
protected async void RunHelpAbout(Window currentWindow)
{
if (this.AboutEnabled)
if (AboutEnabled)
try
{
this.AboutEnabled = false;
await new AboutWindow(IsDarkTheme(this._themeSwitch.Current)).ShowDialog(currentWindow);
AboutEnabled = false;
await new AboutWindow(IsDarkTheme(_themeSwitch.Current)).ShowDialog(currentWindow);
}
finally
{
this.AboutEnabled = true;
AboutEnabled = true;
}
}
protected void SetTheme(ApplicationTheme theme)
{
this.IntializeTheme(theme);
this._themeSwitch.ChangeTheme(theme);
IntializeTheme(theme);
_themeSwitch.ChangeTheme(theme);
}
private void RunFileExit() => Environment.Exit(0);
[Command]
private void FileExit() => Environment.Exit(0);
private void IntializeTheme(ApplicationTheme theme)
{
this.DefaultLightEnabled = theme != ApplicationTheme.SimpleLight;
this.DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark;
this.FluentLightEnabled = theme != ApplicationTheme.FluentLight;
this.FluentDarkEnabled = theme != ApplicationTheme.FluentDark;
DefaultLightEnabled = theme != ApplicationTheme.SimpleLight;
DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark;
FluentLightEnabled = theme != ApplicationTheme.FluentLight;
FluentDarkEnabled = theme != ApplicationTheme.FluentDark;
}
private static Boolean IsDarkTheme(ApplicationTheme? theme)
=> theme switch
private static bool IsDarkTheme(ApplicationTheme? theme) =>
theme switch
{
ApplicationTheme.SimpleDark => true,
ApplicationTheme.FluentDark => true,

View File

@ -1,24 +1,27 @@
using Avalonia.Controls;
using AvaloniaCoreRTDemo.Interfaces;
using MvvmGen;
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)
public MainViewModel(TWindow window) : base(window.ThemeSwitch)
{
this._window = window;
_window = window;
}
public override void HelpAboutMethod() => base.RunHelpAbout(this._window);
public override void DefaultLightMethod() => base.SetTheme(ApplicationTheme.SimpleLight);
public override void DefaultDarkMethod() => base.SetTheme(ApplicationTheme.SimpleDark);
public override void FluentLightMethod() => base.SetTheme(ApplicationTheme.FluentLight);
public override void FluentDarkMethod() => base.SetTheme(ApplicationTheme.FluentDark);
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);
}
}