Avalonia UI 11 Preview 5
* Menu fixes for macOS. * Delete nuget.config. * Nullable enabled. * Fixes in ViewModel class names. * ViewModel for MainControl as MainWindow state. * Preserve window state when swapping Fluent and Simple themes.
This commit is contained in:
		| @@ -1,10 +1,17 @@ | |||||||
| <Application xmlns="https://github.com/avaloniaui" | <Application xmlns="https://github.com/avaloniaui" | ||||||
|              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||||
|              x:Class="AvaloniaCoreRTDemo.App"> |              xmlns:viewModels1="clr-namespace:AvaloniaCoreRTDemo.Windows.ViewModels" | ||||||
|  | 			 RequestedThemeVariant="Light" | ||||||
|  |              x:Class="AvaloniaCoreRTDemo.App" | ||||||
|  | 		     x:CompileBindings="True" | ||||||
|  |              x:DataType="viewModels1:ApplicationModelBase"> | ||||||
|  | 	<NativeMenu.Menu> | ||||||
|  | 		<NativeMenu> | ||||||
|  | 			<NativeMenuItem Header="About" Gesture="cmd+b" IsEnabled="{Binding AboutEnabled}" Command="{Binding HelpAboutMethod}"/> | ||||||
|  | 		</NativeMenu> | ||||||
|  | 	</NativeMenu.Menu> | ||||||
| 	<Application.Resources> | 	<Application.Resources> | ||||||
| 		<StyleInclude x:Key="fluentDataGrid" Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" /> | 		<StyleInclude x:Key="fluentDataGrid" Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" /> | ||||||
| 		<StyleInclude x:Key="simpleDataGrid" Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml" /> | 		<StyleInclude x:Key="simpleDataGrid" Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml" /> | ||||||
| 		<FluentTheme x:Key="fluentTheme" Mode="Light" /> |  | ||||||
| 		<SimpleTheme x:Key="simpleTheme" Mode="Light" /> |  | ||||||
| 	</Application.Resources> | 	</Application.Resources> | ||||||
| </Application> | </Application> | ||||||
| @@ -1,6 +1,6 @@ | |||||||
|  |  | ||||||
| using System; | using System; | ||||||
| using Avalonia; | using Avalonia; | ||||||
|  | using Avalonia.Controls; | ||||||
| using Avalonia.Controls.ApplicationLifetimes; | using Avalonia.Controls.ApplicationLifetimes; | ||||||
| using Avalonia.Markup.Xaml; | using Avalonia.Markup.Xaml; | ||||||
| using Avalonia.Styling; | using Avalonia.Styling; | ||||||
| @@ -13,10 +13,10 @@ namespace AvaloniaCoreRTDemo | |||||||
| { | { | ||||||
|     public sealed class App : Application, IThemeSwitch |     public sealed class App : Application, IThemeSwitch | ||||||
|     { |     { | ||||||
|         private FluentTheme _fluentTheme; |         private FluentTheme _fluentTheme = default!; | ||||||
|         private SimpleTheme _simpleTheme; |         private SimpleTheme _simpleTheme = default!; | ||||||
|         private IStyle _fluentDataGrid; |         private IStyle _fluentDataGrid = default!; | ||||||
|         private IStyle _simpleDataGrid; |         private IStyle _simpleDataGrid = default!; | ||||||
|  |  | ||||||
|         private ApplicationTheme _currentTheme; |         private ApplicationTheme _currentTheme; | ||||||
|  |  | ||||||
| @@ -39,13 +39,14 @@ namespace AvaloniaCoreRTDemo | |||||||
|  |  | ||||||
|         private void InitializeThemes() |         private void InitializeThemes() | ||||||
|         { |         { | ||||||
|             this._fluentTheme = (FluentTheme)this.Resources["fluentTheme"]!; |             this._simpleTheme = new SimpleTheme(); | ||||||
|             this._simpleTheme = (SimpleTheme)this.Resources["simpleTheme"]!; |             this._fluentTheme = new FluentTheme(); | ||||||
|  |  | ||||||
|             this._fluentDataGrid = (IStyle)this.Resources["fluentDataGrid"]!; |             this._fluentDataGrid = (IStyle)this.Resources["fluentDataGrid"]!; | ||||||
|             this._simpleDataGrid = (IStyle)this.Resources["simpleDataGrid"]!; |             this._simpleDataGrid = (IStyle)this.Resources["simpleDataGrid"]!; | ||||||
|  |  | ||||||
|             Styles.Add(_fluentTheme); |             Styles.Add(_fluentTheme); | ||||||
|             Styles.Add(_fluentDataGrid); |             Styles.Add(_fluentDataGrid); | ||||||
|  |  | ||||||
|             this._currentTheme = ApplicationTheme.FluentLight; |             this._currentTheme = ApplicationTheme.FluentLight; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -53,12 +54,15 @@ namespace AvaloniaCoreRTDemo | |||||||
|  |  | ||||||
|         void IThemeSwitch.ChangeTheme(ApplicationTheme theme) |         void IThemeSwitch.ChangeTheme(ApplicationTheme theme) | ||||||
|         { |         { | ||||||
|             var themeChanged = theme switch |             if (theme == this._currentTheme) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             Boolean themeChanged = theme switch | ||||||
|             { |             { | ||||||
|                 ApplicationTheme.SimpleLight => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, |                 ApplicationTheme.SimpleLight => this._currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, | ||||||
|                 ApplicationTheme.SimpleDark => _currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, |                 ApplicationTheme.SimpleDark => this._currentTheme is ApplicationTheme.FluentDark or ApplicationTheme.FluentLight, | ||||||
|                 ApplicationTheme.FluentLight => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, |                 ApplicationTheme.FluentLight => this._currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, | ||||||
|                 ApplicationTheme.FluentDark => _currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, |                 ApplicationTheme.FluentDark => this._currentTheme is ApplicationTheme.SimpleLight or ApplicationTheme.SimpleDark, | ||||||
|                 _ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null) |                 _ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null) | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
| @@ -66,35 +70,36 @@ namespace AvaloniaCoreRTDemo | |||||||
|             switch (theme) |             switch (theme) | ||||||
|             { |             { | ||||||
|                 case ApplicationTheme.SimpleLight: |                 case ApplicationTheme.SimpleLight: | ||||||
|                     this._simpleTheme.Mode = SimpleThemeMode.Light; |                     this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); | ||||||
|                     this.Styles[0] = this._simpleTheme; |                     this.Styles[0] = this._simpleTheme; | ||||||
|                     this.Styles[1] = this._simpleDataGrid; |                     this.Styles[1] = this._simpleDataGrid; | ||||||
|                     break; |                     break; | ||||||
|                 case ApplicationTheme.SimpleDark: |                 case ApplicationTheme.SimpleDark: | ||||||
|                     this._simpleTheme.Mode = SimpleThemeMode.Dark; |                     this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); | ||||||
|                     this.Styles[0] = this._simpleTheme; |                     this.Styles[0] = this._simpleTheme; | ||||||
|                     this.Styles[1] = this._simpleDataGrid; |                     this.Styles[1] = this._simpleDataGrid; | ||||||
|                     break; |                     break; | ||||||
|                 case ApplicationTheme.FluentLight: |                 case ApplicationTheme.FluentLight: | ||||||
|                     this._fluentTheme.Mode = FluentThemeMode.Light; |                     this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); | ||||||
|                     this.Styles[0] = this._fluentTheme; |                     this.Styles[0] = this._fluentTheme; | ||||||
|                     this.Styles[1] = this._fluentDataGrid; |                     this.Styles[1] = this._fluentDataGrid; | ||||||
|                     break; |                     break; | ||||||
|                 case ApplicationTheme.FluentDark: |                 case ApplicationTheme.FluentDark: | ||||||
|                     this._fluentTheme.Mode = FluentThemeMode.Dark; |                     this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); | ||||||
|                     this.Styles[0] = this._fluentTheme; |                     this.Styles[0] = this._fluentTheme; | ||||||
|                     this.Styles[1] = this._fluentDataGrid; |                     this.Styles[1] = this._fluentDataGrid; | ||||||
|                     break; |                     break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) |             if (themeChanged && this.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) | ||||||
|             { |             { | ||||||
|                 var oldWindow = desktop.MainWindow; |                 MainWindow oldWindow = (desktop.MainWindow as MainWindow)!; | ||||||
|                 var newWindow = new MainWindow(); |                 MainWindow newWindow = new MainWindow(oldWindow); | ||||||
|  |  | ||||||
|                 desktop.MainWindow = newWindow; |                 desktop.MainWindow = newWindow; | ||||||
|  |                 this.DataContext = newWindow.DataContext; | ||||||
|                 newWindow.Show(); |                 newWindow.Show(); | ||||||
|                 oldWindow.Close(); |                 oldWindow.Close(); | ||||||
|                 this.DataContext = desktop.MainWindow.DataContext; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ | |||||||
|     <ApplicationIcon>Assets/app.ico</ApplicationIcon> |     <ApplicationIcon>Assets/app.ico</ApplicationIcon> | ||||||
|     <InvariantGlobalization>true</InvariantGlobalization> |     <InvariantGlobalization>true</InvariantGlobalization> | ||||||
|     <PublishAot>true</PublishAot> |     <PublishAot>true</PublishAot> | ||||||
|  |     <Nullable>enable</Nullable> | ||||||
|     <IsWindows Condition="$([MSBuild]::IsOSPlatform('Windows'))">true</IsWindows> |     <IsWindows Condition="$([MSBuild]::IsOSPlatform('Windows'))">true</IsWindows> | ||||||
|     <IsLinux Condition="$([MSBuild]::IsOSPlatform('Linux'))">true</IsLinux> |     <IsLinux Condition="$([MSBuild]::IsOSPlatform('Linux'))">true</IsLinux> | ||||||
|     <IsOSX Condition="$([MSBuild]::IsOSPlatform('OSX'))">true</IsOSX> |     <IsOSX Condition="$([MSBuild]::IsOSPlatform('OSX'))">true</IsOSX> | ||||||
| @@ -40,14 +40,14 @@ | |||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|      |      | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Avalonia" Version="11.0.999-cibuild0026389-beta" /> |     <PackageReference Include="Avalonia" Version="11.0.0-*" /> | ||||||
|     <PackageReference Include="Avalonia.Desktop" Version="11.0.999-cibuild0026389-beta" /> |     <PackageReference Include="Avalonia.Desktop" Version="11.0.0-*" /> | ||||||
|     <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.999-cibuild0026389-beta" /> |     <PackageReference Include="Avalonia.Controls.DataGrid" Version="11.0.0-*" /> | ||||||
|     <PackageReference Include="Avalonia.ReactiveUI" Version="11.0.999-cibuild0026389-beta" /> |     <PackageReference Include="Avalonia.ReactiveUI" Version="11.0.0-*" /> | ||||||
|     <PackageReference Include="Avalonia.Themes.Simple" Version="11.0.999-cibuild0026389-beta" /> |     <PackageReference Include="Avalonia.Themes.Simple" Version="11.0.0-*" /> | ||||||
|     <PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.999-cibuild0026389-beta" /> |     <PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-*" /> | ||||||
|     <!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.--> |     <!--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.999-cibuild0026389-beta" /> |     <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-*" /> | ||||||
|     <!--Condition below is needed to generate macOS App only.--> |     <!--Condition below is needed to generate macOS App only.--> | ||||||
|     <PackageReference Include="Dotnet.Bundle" Version="*" Condition="$(RuntimeIdentifier.StartsWith('osx'))" /> |     <PackageReference Include="Dotnet.Bundle" Version="*" Condition="$(RuntimeIdentifier.StartsWith('osx'))" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   | |||||||
| @@ -2,11 +2,11 @@ | |||||||
|              xmlns:viewModels="clr-namespace:AvaloniaCoreRTDemo.Controls.ViewModels" |              xmlns:viewModels="clr-namespace:AvaloniaCoreRTDemo.Controls.ViewModels" | ||||||
|              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Controls.MainControl" |              mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Controls.MainControl" | ||||||
| 			 x:CompileBindings="True" | 			 x:CompileBindings="True" | ||||||
| 			 x:DataType="viewModels:MainViewModel"> | 			 x:DataType="viewModels:MainControlViewModel"> | ||||||
| 	<Grid ColumnDefinitions="*,*" RowDefinitions="Auto,Auto,*" Margin="32"> | 	<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> | 		<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="0" Stretch="None" Source="{Binding DotNetImage}"/> | ||||||
| 		<Image Grid.Row="1" Grid.Column="1" Stretch="None" Source="{Binding AvaloniaImage}"/> | 		<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"/> | 		<TextBox Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Watermark="Type here" AcceptsReturn="True" TextWrapping="Wrap" Text="{Binding Text}"/> | ||||||
| 	</Grid> | 	</Grid> | ||||||
| </UserControl> | </UserControl> | ||||||
|   | |||||||
| @@ -9,13 +9,19 @@ namespace AvaloniaCoreRTDemo.Controls | |||||||
|     { |     { | ||||||
|         public MainControl() |         public MainControl() | ||||||
|         { |         { | ||||||
|             InitializeComponent(); |             this.InitializeComponent(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void InitializeComponent() |         private void InitializeComponent() | ||||||
|         { |         { | ||||||
|             AvaloniaXamlLoader.Load(this); |             AvaloniaXamlLoader.Load(this); | ||||||
|             this.DataContext = new MainViewModel(); |             this.DataContext = new MainControlViewModel(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Reload(IMainWindowState? model) | ||||||
|  |         { | ||||||
|  |             if(model is not null) | ||||||
|  |                 this.DataContext = new MainControlViewModel(model); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										49
									
								
								src/Controls/ViewModels/MainControlViewModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/Controls/ViewModels/MainControlViewModel.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | |||||||
|  | using System; | ||||||
|  | using System.IO; | ||||||
|  |  | ||||||
|  | using Avalonia.Media.Imaging; | ||||||
|  | using AvaloniaCoreRTDemo.Interfaces; | ||||||
|  | using ReactiveUI; | ||||||
|  |  | ||||||
|  | namespace AvaloniaCoreRTDemo.Controls.ViewModels | ||||||
|  | { | ||||||
|  |     internal sealed class MainControlViewModel : ReactiveObject, IMainWindowState | ||||||
|  |     { | ||||||
|  |         private readonly IBitmap _dotNetImage; | ||||||
|  |         private readonly IBitmap _avaloniaImage; | ||||||
|  |  | ||||||
|  |         private Boolean _unloadable = false; | ||||||
|  |  | ||||||
|  |         public IBitmap DotNetImage => this._dotNetImage; | ||||||
|  |         public IBitmap AvaloniaImage => this._avaloniaImage; | ||||||
|  |         public String? Text { get; set; } | ||||||
|  |  | ||||||
|  |         public MainControlViewModel() | ||||||
|  |         { | ||||||
|  |             this._dotNetImage = Utilities.GetImageFromFile("dotnet.png"); | ||||||
|  |             this._avaloniaImage = Utilities.GetImageFromFile("avalonia.png"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public MainControlViewModel(IMainWindowState state) | ||||||
|  |         { | ||||||
|  |             this._avaloniaImage = state.AvaloniaImage; | ||||||
|  |             this._dotNetImage = state.DotNetImage; | ||||||
|  |             this.Text = state.Text; | ||||||
|  |             state.SetUnloadable(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         ~MainControlViewModel() | ||||||
|  |         { | ||||||
|  |             if (!this._unloadable) | ||||||
|  |             { | ||||||
|  |                 this._dotNetImage.Dispose(); | ||||||
|  |                 this._avaloniaImage.Dispose(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         void IMainWindowState.SetUnloadable() | ||||||
|  |         { | ||||||
|  |             this._unloadable = true; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,31 +0,0 @@ | |||||||
| using System; |  | ||||||
| using System.IO; |  | ||||||
|  |  | ||||||
| using Avalonia.Media.Imaging; |  | ||||||
|  |  | ||||||
| using ReactiveUI; |  | ||||||
|  |  | ||||||
| namespace AvaloniaCoreRTDemo.Controls.ViewModels |  | ||||||
| { |  | ||||||
|     internal sealed class MainViewModel : ReactiveObject |  | ||||||
|     { |  | ||||||
|         private readonly IBitmap _dotNetImage; |  | ||||||
|         private readonly IBitmap _avaloniaImage; |  | ||||||
|  |  | ||||||
|         public IBitmap DotNetImage => this._dotNetImage; |  | ||||||
|  |  | ||||||
|         public IBitmap AvaloniaImage => this._avaloniaImage; |  | ||||||
|  |  | ||||||
|         public MainViewModel() |  | ||||||
|         { |  | ||||||
|             this._dotNetImage = Utilities.GetImageFromFile("dotnet.png"); |  | ||||||
|             this._avaloniaImage = Utilities.GetImageFromFile("avalonia.png"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         ~MainViewModel() |  | ||||||
|         { |  | ||||||
|             this._dotNetImage.Dispose(); |  | ||||||
|             this._avaloniaImage.Dispose(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,9 +1,10 @@ | |||||||
| using AvaloniaCoreRTDemo.Interfaces; | using Avalonia.Controls; | ||||||
|  |  | ||||||
| namespace AvaloniaCoreRTDemo | namespace AvaloniaCoreRTDemo.Interfaces | ||||||
| { | { | ||||||
|     public interface IMainWindow |     public interface IMainWindow | ||||||
|     { |     { | ||||||
|         IThemeSwitch ThemeSwitch { get; } |         IThemeSwitch ThemeSwitch { get; } | ||||||
|  |         IMainWindowState Model { get; } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/Interfaces/IMainWindowState.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/Interfaces/IMainWindowState.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | using System; | ||||||
|  | using Avalonia.Media.Imaging; | ||||||
|  |  | ||||||
|  | namespace AvaloniaCoreRTDemo | ||||||
|  | { | ||||||
|  | 	public interface IMainWindowState | ||||||
|  | 	{ | ||||||
|  |         IBitmap DotNetImage { get; } | ||||||
|  |         IBitmap AvaloniaImage { get; } | ||||||
|  |         String? Text { get; } | ||||||
|  |  | ||||||
|  |         void SetUnloadable(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| using System; | using System; | ||||||
|  | using Avalonia; | ||||||
| using Avalonia.Controls; | using Avalonia.Controls; | ||||||
| using Avalonia.Markup.Xaml; | using Avalonia.Markup.Xaml; | ||||||
|  |  | ||||||
| @@ -9,14 +9,14 @@ namespace AvaloniaCoreRTDemo.Windows | |||||||
| { | { | ||||||
|     public sealed partial class AboutWindow : Window |     public sealed partial class AboutWindow : Window | ||||||
|     { |     { | ||||||
|         public AboutWindow() |         public AboutWindow() : this(false) { } | ||||||
|         { |  | ||||||
|             this.InitializeComponent(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public AboutWindow(Boolean darkTheme) |         public AboutWindow(Boolean darkTheme) | ||||||
|         { |         { | ||||||
|             this.InitializeComponent(darkTheme); |             this.InitializeComponent(darkTheme); | ||||||
|  | #if DEBUG | ||||||
|  |             this.AttachDevTools(); | ||||||
|  | #endif | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void InitializeComponent(Boolean darkTheme = default) |         private void InitializeComponent(Boolean darkTheme = default) | ||||||
|   | |||||||
| @@ -4,10 +4,10 @@ | |||||||
|         mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Windows.MainWindow" |         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" |         Width="640" Height="480" WindowStartupLocation="CenterScreen" Title="AvaloniaCoreRTDemo" Icon="avares://AvaloniaCoreRTDemo/Assets/app.ico" MinWidth="400" MinHeight="350" | ||||||
|         x:CompileBindings="True" |         x:CompileBindings="True" | ||||||
|         x:DataType="viewModels1:MainViewModelBase"> |         x:DataType="viewModels1:ApplicationModelBase"> | ||||||
|     <DockPanel> |     <DockPanel> | ||||||
|         <NativeMenuBar DockPanel.Dock="Top" /> |         <NativeMenuBar DockPanel.Dock="Top" /> | ||||||
|         <controls:MainControl/> |         <controls:MainControl Name="mainControl"/> | ||||||
|     </DockPanel> |     </DockPanel> | ||||||
|     <NativeMenu.Menu> |     <NativeMenu.Menu> | ||||||
|         <NativeMenu> |         <NativeMenu> | ||||||
|   | |||||||
| @@ -1,7 +1,10 @@ | |||||||
|  | using System; | ||||||
| using Avalonia; | using Avalonia; | ||||||
| using Avalonia.Controls; | using Avalonia.Controls; | ||||||
|  | using Avalonia.Controls.ApplicationLifetimes; | ||||||
| using Avalonia.Markup.Xaml; | using Avalonia.Markup.Xaml; | ||||||
|  | using AvaloniaCoreRTDemo.Controls; | ||||||
|  | using AvaloniaCoreRTDemo.Controls.ViewModels; | ||||||
| using AvaloniaCoreRTDemo.Interfaces; | using AvaloniaCoreRTDemo.Interfaces; | ||||||
| using AvaloniaCoreRTDemo.Windows.ViewModels; | using AvaloniaCoreRTDemo.Windows.ViewModels; | ||||||
|  |  | ||||||
| @@ -9,20 +12,25 @@ namespace AvaloniaCoreRTDemo.Windows | |||||||
| { | { | ||||||
|     public sealed partial class MainWindow : Window, IMainWindow |     public sealed partial class MainWindow : Window, IMainWindow | ||||||
|     { |     { | ||||||
|         public MainWindow() |         private readonly Application? _app = App.Current; | ||||||
|  |  | ||||||
|  |         public MainWindow() : this(default) { }         | ||||||
|  |         public MainWindow(IMainWindow? window) | ||||||
|         { |         { | ||||||
|             InitializeComponent(); |             this.InitializeComponent(window); | ||||||
| #if DEBUG | #if DEBUG | ||||||
|             this.AttachDevTools(); |             this.AttachDevTools(); | ||||||
| #endif | #endif | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void InitializeComponent() |         IThemeSwitch IMainWindow.ThemeSwitch => (this._app as IThemeSwitch)!; | ||||||
|  |         IMainWindowState IMainWindow.Model => (this.GetControl<MainControl>("mainControl")!.DataContext as IMainWindowState)!; | ||||||
|  |  | ||||||
|  |         private void InitializeComponent(IMainWindow? window) | ||||||
|         { |         { | ||||||
|             AvaloniaXamlLoader.Load(this); |             AvaloniaXamlLoader.Load(this); | ||||||
|             this.DataContext = new MainViewModel<MainWindow>(this); |             this.DataContext = new MainViewModel<MainWindow>(this); | ||||||
|  |             this.GetControl<MainControl>("mainControl").Reload(window?.Model); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         IThemeSwitch IMainWindow.ThemeSwitch => App.Current as IThemeSwitch; |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -8,7 +8,7 @@ using ReactiveUI; | |||||||
|  |  | ||||||
| namespace AvaloniaCoreRTDemo.Windows.ViewModels | namespace AvaloniaCoreRTDemo.Windows.ViewModels | ||||||
| { | { | ||||||
|     internal record SystemDetail(string Key, string Value); |     internal record SystemDetail(String Key, String Value); | ||||||
|      |      | ||||||
|     internal sealed class AboutViewModel : ReactiveObject |     internal sealed class AboutViewModel : ReactiveObject | ||||||
|     { |     { | ||||||
|   | |||||||
| @@ -8,14 +8,14 @@ using ReactiveUI; | |||||||
| 
 | 
 | ||||||
| namespace AvaloniaCoreRTDemo.Windows.ViewModels | namespace AvaloniaCoreRTDemo.Windows.ViewModels | ||||||
| { | { | ||||||
|     internal abstract class MainViewModelBase : ReactiveObject |     internal abstract class ApplicationModelBase : ReactiveObject | ||||||
|     { |     { | ||||||
|         private readonly IThemeSwitch _themeSwitch; |         private readonly IThemeSwitch _themeSwitch; | ||||||
|         private Boolean _aboutEnable = true; |         private Boolean _aboutEnable = true; | ||||||
|         private Boolean _defaultLightEnable = true; |         private Boolean _defaultLightEnable = false; | ||||||
|         private Boolean _defaultDarkEnable = true; |         private Boolean _defaultDarkEnable = false; | ||||||
|         private Boolean _fluentLightEnable = true; |         private Boolean _fluentLightEnable = false; | ||||||
|         private Boolean _fluentDarkEnable = true; |         private Boolean _fluentDarkEnable = false; | ||||||
| 
 | 
 | ||||||
|         public Boolean AboutEnabled |         public Boolean AboutEnabled | ||||||
|         { |         { | ||||||
| @@ -23,12 +23,6 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels | |||||||
|             set => this.RaiseAndSetIfChanged(ref this._aboutEnable, value); |             set => this.RaiseAndSetIfChanged(ref this._aboutEnable, value); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public MainViewModelBase(IThemeSwitch window) |  | ||||||
|         { |  | ||||||
|             this._themeSwitch = window; |  | ||||||
|             this.FileExitCommand = ReactiveCommand.Create(RunFileExit); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public Boolean DefaultLightEnabled |         public Boolean DefaultLightEnabled | ||||||
|         { |         { | ||||||
|             get => this._defaultLightEnable; |             get => this._defaultLightEnable; | ||||||
| @@ -55,16 +49,19 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels | |||||||
|          |          | ||||||
|         public ReactiveCommand<Unit, Unit> FileExitCommand { get; } |         public ReactiveCommand<Unit, Unit> FileExitCommand { get; } | ||||||
| 
 | 
 | ||||||
|         public abstract void HelpAboutMethod(); |         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 DefaultLightMethod(); | ||||||
|         public abstract void DefaultDarkMethod(); |         public abstract void DefaultDarkMethod(); | ||||||
|         public abstract void FluentLightMethod(); |         public abstract void FluentLightMethod(); | ||||||
|         public abstract void FluentDarkMethod(); |         public abstract void FluentDarkMethod(); | ||||||
| 
 | 
 | ||||||
|         private void RunFileExit() |  | ||||||
|             => Environment.Exit(0); |  | ||||||
|          |  | ||||||
|         protected async void RunHelpAbout(Window currentWindow) |         protected async void RunHelpAbout(Window currentWindow) | ||||||
|         { |         { | ||||||
|             if (this.AboutEnabled) |             if (this.AboutEnabled) | ||||||
| @@ -79,6 +76,22 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels | |||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         protected void SetTheme(ApplicationTheme theme) | ||||||
|  |         { | ||||||
|  |             this.IntializeTheme(theme); | ||||||
|  |             this._themeSwitch.ChangeTheme(theme); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void RunFileExit() => 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; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         private static Boolean IsDarkTheme(ApplicationTheme? theme) |         private static Boolean IsDarkTheme(ApplicationTheme? theme) | ||||||
|             => theme switch |             => theme switch | ||||||
|             { |             { | ||||||
| @@ -2,38 +2,27 @@ | |||||||
| using System.Reactive; | using System.Reactive; | ||||||
|  |  | ||||||
| using Avalonia.Controls; | using Avalonia.Controls; | ||||||
|  | using AvaloniaCoreRTDemo.Controls.ViewModels; | ||||||
|  | using AvaloniaCoreRTDemo.Interfaces; | ||||||
| using ReactiveUI; | using ReactiveUI; | ||||||
|  |  | ||||||
| namespace AvaloniaCoreRTDemo.Windows.ViewModels | namespace AvaloniaCoreRTDemo.Windows.ViewModels | ||||||
| { | { | ||||||
|     internal sealed class MainViewModel<TWindow> : MainViewModelBase |     internal sealed class MainViewModel<TWindow> : ApplicationModelBase | ||||||
|         where TWindow : Window, IMainWindow |         where TWindow : Window, IMainWindow | ||||||
|     { |     { | ||||||
|         private readonly TWindow _window; |         private TWindow _window; | ||||||
|  |  | ||||||
|         public MainViewModel(TWindow window) |         public MainViewModel(TWindow window) | ||||||
|             : base(window.ThemeSwitch) |             : base(window.ThemeSwitch) | ||||||
|         { |         { | ||||||
|             this._window = window; |             this._window = window; | ||||||
|             this.ChangeTheme(window.ThemeSwitch.Current); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|         public override void HelpAboutMethod() => base.RunHelpAbout(this._window); |         public override void HelpAboutMethod() => base.RunHelpAbout(this._window); | ||||||
|  |         public override void DefaultLightMethod() => base.SetTheme(ApplicationTheme.SimpleLight); | ||||||
|         public override void DefaultLightMethod() => this.ChangeTheme(ApplicationTheme.SimpleLight); |         public override void DefaultDarkMethod() => base.SetTheme(ApplicationTheme.SimpleDark); | ||||||
|         public override void DefaultDarkMethod() => this.ChangeTheme(ApplicationTheme.SimpleDark); |         public override void FluentLightMethod() => base.SetTheme(ApplicationTheme.FluentLight); | ||||||
|         public override void FluentLightMethod() => this.ChangeTheme(ApplicationTheme.FluentLight); |         public override void FluentDarkMethod() => base.SetTheme(ApplicationTheme.FluentDark); | ||||||
|         public override void FluentDarkMethod() => this.ChangeTheme(ApplicationTheme.FluentDark); |  | ||||||
|          |  | ||||||
|         private void ChangeTheme(ApplicationTheme theme) |  | ||||||
|         { |  | ||||||
|             this.DefaultLightEnabled = theme != ApplicationTheme.SimpleLight; |  | ||||||
|             this.DefaultDarkEnabled = theme != ApplicationTheme.SimpleDark; |  | ||||||
|             this.FluentLightEnabled = theme != ApplicationTheme.FluentLight; |  | ||||||
|             this.FluentDarkEnabled = theme != ApplicationTheme.FluentDark; |  | ||||||
|             this._window.ThemeSwitch?.ChangeTheme(theme); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <configuration> |  | ||||||
|   <packageSources> |  | ||||||
|     <add key="avalonia" value="https://nuget.avaloniaui.net/repository/avalonia-all/index.json" /> |  | ||||||
|     <add key="nuget" value="https://api.nuget.org/v3/index.json" /> |  | ||||||
|   </packageSources> |  | ||||||
| </configuration> |  | ||||||
		Reference in New Issue
	
	Block a user
	 Joseph Moreno
					Joseph Moreno