From defcc0b3601052e34859c0dd58e7f6dc29fbee4a Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Tue, 7 Feb 2023 23:34:30 -0500 Subject: [PATCH 01/13] 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. --- src/App.axaml | 13 +++-- src/App.axaml.cs | 49 ++++++++++--------- src/AvaloniaCoreRTDemo.csproj | 16 +++--- src/Controls/MainControl.axaml | 4 +- src/Controls/MainControl.axaml.cs | 10 +++- .../ViewModels/MainControlViewModel.cs | 49 +++++++++++++++++++ src/Controls/ViewModels/MainViewModel.cs | 31 ------------ src/Interfaces/IMainWindow.cs | 5 +- src/Interfaces/IMainWindowState.cs | 15 ++++++ src/Windows/AboutWindow.axaml.cs | 10 ++-- src/Windows/MainWindow.axaml | 4 +- src/Windows/MainWindow.axaml.cs | 20 +++++--- src/Windows/ViewModels/AboutViewModel.cs | 2 +- ...ewModelBase.cs => ApplicationModelBase.cs} | 47 +++++++++++------- src/Windows/ViewModels/MainViewModel.cs | 27 +++------- src/nuget.config | 7 --- 16 files changed, 182 insertions(+), 127 deletions(-) create mode 100644 src/Controls/ViewModels/MainControlViewModel.cs delete mode 100644 src/Controls/ViewModels/MainViewModel.cs create mode 100644 src/Interfaces/IMainWindowState.cs rename src/Windows/ViewModels/{MainViewModelBase.cs => ApplicationModelBase.cs} (68%) delete mode 100644 src/nuget.config diff --git a/src/App.axaml b/src/App.axaml index 65e3c87..bc3aa7a 100644 --- a/src/App.axaml +++ b/src/App.axaml @@ -1,10 +1,17 @@ + xmlns:viewModels1="clr-namespace:AvaloniaCoreRTDemo.Windows.ViewModels" + RequestedThemeVariant="Light" + x:Class="AvaloniaCoreRTDemo.App" + x:CompileBindings="True" + x:DataType="viewModels1:ApplicationModelBase"> + + + + + - - \ No newline at end of file diff --git a/src/App.axaml.cs b/src/App.axaml.cs index e0ead4d..57d31d4 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -1,6 +1,6 @@ - using System; using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using Avalonia.Styling; @@ -13,10 +13,10 @@ namespace AvaloniaCoreRTDemo { public sealed class App : Application, IThemeSwitch { - private FluentTheme _fluentTheme; - private SimpleTheme _simpleTheme; - private IStyle _fluentDataGrid; - private IStyle _simpleDataGrid; + private FluentTheme _fluentTheme = default!; + private SimpleTheme _simpleTheme = default!; + private IStyle _fluentDataGrid = default!; + private IStyle _simpleDataGrid = default!; private ApplicationTheme _currentTheme; @@ -39,13 +39,14 @@ namespace AvaloniaCoreRTDemo private void InitializeThemes() { - this._fluentTheme = (FluentTheme)this.Resources["fluentTheme"]!; - this._simpleTheme = (SimpleTheme)this.Resources["simpleTheme"]!; + this._simpleTheme = new SimpleTheme(); + this._fluentTheme = new FluentTheme(); + this._fluentDataGrid = (IStyle)this.Resources["fluentDataGrid"]!; this._simpleDataGrid = (IStyle)this.Resources["simpleDataGrid"]!; + Styles.Add(_fluentTheme); Styles.Add(_fluentDataGrid); - this._currentTheme = ApplicationTheme.FluentLight; } @@ -53,48 +54,52 @@ namespace AvaloniaCoreRTDemo 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.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, + 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, _ => throw new ArgumentOutOfRangeException(nameof(theme), theme, null) }; - + this._currentTheme = theme; switch (theme) { case ApplicationTheme.SimpleLight: - this._simpleTheme.Mode = SimpleThemeMode.Light; + this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); this.Styles[0] = this._simpleTheme; this.Styles[1] = this._simpleDataGrid; break; case ApplicationTheme.SimpleDark: - this._simpleTheme.Mode = SimpleThemeMode.Dark; + this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); this.Styles[0] = this._simpleTheme; this.Styles[1] = this._simpleDataGrid; break; case ApplicationTheme.FluentLight: - this._fluentTheme.Mode = FluentThemeMode.Light; + this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Light); this.Styles[0] = this._fluentTheme; this.Styles[1] = this._fluentDataGrid; break; case ApplicationTheme.FluentDark: - this._fluentTheme.Mode = FluentThemeMode.Dark; + this.SetValue(ThemeVariantScope.ActualThemeVariantProperty, ThemeVariant.Dark); this.Styles[0] = this._fluentTheme; this.Styles[1] = this._fluentDataGrid; break; } - if (themeChanged && ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + if (themeChanged && this.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { - var oldWindow = desktop.MainWindow; - var newWindow = new MainWindow(); + MainWindow oldWindow = (desktop.MainWindow as MainWindow)!; + MainWindow newWindow = new MainWindow(oldWindow); + desktop.MainWindow = newWindow; + this.DataContext = newWindow.DataContext; newWindow.Show(); oldWindow.Close(); - this.DataContext = desktop.MainWindow.DataContext; } } } diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj index 3651354..5a9bdfb 100644 --- a/src/AvaloniaCoreRTDemo.csproj +++ b/src/AvaloniaCoreRTDemo.csproj @@ -8,7 +8,7 @@ Assets/app.ico true true - + enable true true true @@ -40,14 +40,14 @@ - - - - - - + + + + + + - + diff --git a/src/Controls/MainControl.axaml b/src/Controls/MainControl.axaml index d443c2d..13c2ab2 100644 --- a/src/Controls/MainControl.axaml +++ b/src/Controls/MainControl.axaml @@ -2,11 +2,11 @@ xmlns:viewModels="clr-namespace:AvaloniaCoreRTDemo.Controls.ViewModels" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaCoreRTDemo.Controls.MainControl" x:CompileBindings="True" - x:DataType="viewModels:MainViewModel"> + x:DataType="viewModels:MainControlViewModel"> Welcome to Avalonia UI + NativeAOT! - + diff --git a/src/Controls/MainControl.axaml.cs b/src/Controls/MainControl.axaml.cs index 59d7185..13496ee 100644 --- a/src/Controls/MainControl.axaml.cs +++ b/src/Controls/MainControl.axaml.cs @@ -9,13 +9,19 @@ namespace AvaloniaCoreRTDemo.Controls { public MainControl() { - InitializeComponent(); + this.InitializeComponent(); } private void InitializeComponent() { 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); } } } diff --git a/src/Controls/ViewModels/MainControlViewModel.cs b/src/Controls/ViewModels/MainControlViewModel.cs new file mode 100644 index 0000000..0254d8f --- /dev/null +++ b/src/Controls/ViewModels/MainControlViewModel.cs @@ -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; + } + } +} diff --git a/src/Controls/ViewModels/MainViewModel.cs b/src/Controls/ViewModels/MainViewModel.cs deleted file mode 100644 index f1cea96..0000000 --- a/src/Controls/ViewModels/MainViewModel.cs +++ /dev/null @@ -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(); - } - } -} diff --git a/src/Interfaces/IMainWindow.cs b/src/Interfaces/IMainWindow.cs index 2f8b2a8..a670e2f 100644 --- a/src/Interfaces/IMainWindow.cs +++ b/src/Interfaces/IMainWindow.cs @@ -1,9 +1,10 @@ -using AvaloniaCoreRTDemo.Interfaces; +using Avalonia.Controls; -namespace AvaloniaCoreRTDemo +namespace AvaloniaCoreRTDemo.Interfaces { public interface IMainWindow { IThemeSwitch ThemeSwitch { get; } + IMainWindowState Model { get; } } } diff --git a/src/Interfaces/IMainWindowState.cs b/src/Interfaces/IMainWindowState.cs new file mode 100644 index 0000000..752cdac --- /dev/null +++ b/src/Interfaces/IMainWindowState.cs @@ -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(); + } +} + diff --git a/src/Windows/AboutWindow.axaml.cs b/src/Windows/AboutWindow.axaml.cs index 4b9ca92..e1b7aa0 100644 --- a/src/Windows/AboutWindow.axaml.cs +++ b/src/Windows/AboutWindow.axaml.cs @@ -1,5 +1,5 @@ using System; - +using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; @@ -9,14 +9,14 @@ namespace AvaloniaCoreRTDemo.Windows { public sealed partial class AboutWindow : Window { - public AboutWindow() - { - this.InitializeComponent(); - } + public AboutWindow() : this(false) { } public AboutWindow(Boolean darkTheme) { this.InitializeComponent(darkTheme); +#if DEBUG + this.AttachDevTools(); +#endif } private void InitializeComponent(Boolean darkTheme = default) diff --git a/src/Windows/MainWindow.axaml b/src/Windows/MainWindow.axaml index e82bf20..4db5a61 100644 --- a/src/Windows/MainWindow.axaml +++ b/src/Windows/MainWindow.axaml @@ -4,10 +4,10 @@ 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" x:CompileBindings="True" - x:DataType="viewModels1:MainViewModelBase"> + x:DataType="viewModels1:ApplicationModelBase"> - + diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index a846014..3c56369 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -1,7 +1,10 @@ +using System; using Avalonia; using Avalonia.Controls; +using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; - +using AvaloniaCoreRTDemo.Controls; +using AvaloniaCoreRTDemo.Controls.ViewModels; using AvaloniaCoreRTDemo.Interfaces; using AvaloniaCoreRTDemo.Windows.ViewModels; @@ -9,20 +12,25 @@ namespace AvaloniaCoreRTDemo.Windows { 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 this.AttachDevTools(); #endif } - private void InitializeComponent() + IThemeSwitch IMainWindow.ThemeSwitch => (this._app as IThemeSwitch)!; + IMainWindowState IMainWindow.Model => (this.GetControl("mainControl")!.DataContext as IMainWindowState)!; + + private void InitializeComponent(IMainWindow? window) { AvaloniaXamlLoader.Load(this); this.DataContext = new MainViewModel(this); + this.GetControl("mainControl").Reload(window?.Model); } - - IThemeSwitch IMainWindow.ThemeSwitch => App.Current as IThemeSwitch; } } diff --git a/src/Windows/ViewModels/AboutViewModel.cs b/src/Windows/ViewModels/AboutViewModel.cs index 0cb018f..e43bd95 100644 --- a/src/Windows/ViewModels/AboutViewModel.cs +++ b/src/Windows/ViewModels/AboutViewModel.cs @@ -8,7 +8,7 @@ using ReactiveUI; namespace AvaloniaCoreRTDemo.Windows.ViewModels { - internal record SystemDetail(string Key, string Value); + internal record SystemDetail(String Key, String Value); internal sealed class AboutViewModel : ReactiveObject { diff --git a/src/Windows/ViewModels/MainViewModelBase.cs b/src/Windows/ViewModels/ApplicationModelBase.cs similarity index 68% rename from src/Windows/ViewModels/MainViewModelBase.cs rename to src/Windows/ViewModels/ApplicationModelBase.cs index f9d09da..09086e3 100644 --- a/src/Windows/ViewModels/MainViewModelBase.cs +++ b/src/Windows/ViewModels/ApplicationModelBase.cs @@ -8,14 +8,14 @@ using ReactiveUI; namespace AvaloniaCoreRTDemo.Windows.ViewModels { - internal abstract class MainViewModelBase : ReactiveObject + internal abstract class ApplicationModelBase : ReactiveObject { private readonly IThemeSwitch _themeSwitch; private Boolean _aboutEnable = true; - private Boolean _defaultLightEnable = true; - private Boolean _defaultDarkEnable = true; - private Boolean _fluentLightEnable = true; - private Boolean _fluentDarkEnable = true; + private Boolean _defaultLightEnable = false; + private Boolean _defaultDarkEnable = false; + private Boolean _fluentLightEnable = false; + private Boolean _fluentDarkEnable = false; public Boolean AboutEnabled { @@ -23,12 +23,6 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels set => this.RaiseAndSetIfChanged(ref this._aboutEnable, value); } - public MainViewModelBase(IThemeSwitch window) - { - this._themeSwitch = window; - this.FileExitCommand = ReactiveCommand.Create(RunFileExit); - } - public Boolean DefaultLightEnabled { get => this._defaultLightEnable; @@ -54,17 +48,20 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels } public ReactiveCommand 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 DefaultDarkMethod(); public abstract void FluentLightMethod(); public abstract void FluentDarkMethod(); - - private void RunFileExit() - => Environment.Exit(0); - + protected async void RunHelpAbout(Window currentWindow) { 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) => theme switch { diff --git a/src/Windows/ViewModels/MainViewModel.cs b/src/Windows/ViewModels/MainViewModel.cs index 3bd40b8..bf9d68b 100644 --- a/src/Windows/ViewModels/MainViewModel.cs +++ b/src/Windows/ViewModels/MainViewModel.cs @@ -2,38 +2,27 @@ using System.Reactive; using Avalonia.Controls; - +using AvaloniaCoreRTDemo.Controls.ViewModels; +using AvaloniaCoreRTDemo.Interfaces; using ReactiveUI; namespace AvaloniaCoreRTDemo.Windows.ViewModels { - internal sealed class MainViewModel : MainViewModelBase + internal sealed class MainViewModel : ApplicationModelBase where TWindow : Window, IMainWindow { - private readonly TWindow _window; + private TWindow _window; public MainViewModel(TWindow window) : base(window.ThemeSwitch) { this._window = window; - this.ChangeTheme(window.ThemeSwitch.Current); } - public override void HelpAboutMethod() => base.RunHelpAbout(this._window); - - public override void DefaultLightMethod() => this.ChangeTheme(ApplicationTheme.SimpleLight); - public override void DefaultDarkMethod() => this.ChangeTheme(ApplicationTheme.SimpleDark); - public override void FluentLightMethod() => this.ChangeTheme(ApplicationTheme.FluentLight); - 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); - } + 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); } } diff --git a/src/nuget.config b/src/nuget.config deleted file mode 100644 index 3d11832..0000000 --- a/src/nuget.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - From cd2a9d72aabf26856dc990d96e8da5da76b09d28 Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Wed, 8 Feb 2023 00:05:42 -0500 Subject: [PATCH 02/13] * Datagrid fixes --- src/App.axaml.cs | 2 ++ src/Controls/MainControl.axaml.cs | 2 +- src/Controls/ViewModels/MainControlViewModel.cs | 3 +-- src/Interfaces/IMainWindow.cs | 4 +--- src/Interfaces/IMainWindowState.cs | 7 ++++--- src/Utilities.cs | 3 ++- src/Windows/AboutWindow.axaml | 2 +- src/Windows/AboutWindow.axaml.cs | 1 + src/Windows/MainWindow.axaml.cs | 8 +++----- src/Windows/ViewModels/AboutViewModel.cs | 4 ++-- src/Windows/ViewModels/ApplicationModelBase.cs | 3 ++- src/Windows/ViewModels/MainViewModel.cs | 6 +----- 12 files changed, 21 insertions(+), 24 deletions(-) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 57d31d4..0cd350c 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -1,4 +1,5 @@ using System; + using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; @@ -6,6 +7,7 @@ using Avalonia.Markup.Xaml; using Avalonia.Styling; using Avalonia.Themes.Fluent; using Avalonia.Themes.Simple; + using AvaloniaCoreRTDemo.Interfaces; using AvaloniaCoreRTDemo.Windows; diff --git a/src/Controls/MainControl.axaml.cs b/src/Controls/MainControl.axaml.cs index 13496ee..c3cde67 100644 --- a/src/Controls/MainControl.axaml.cs +++ b/src/Controls/MainControl.axaml.cs @@ -20,7 +20,7 @@ namespace AvaloniaCoreRTDemo.Controls public void Reload(IMainWindowState? model) { - if(model is not null) + if (model is not null) this.DataContext = new MainControlViewModel(model); } } diff --git a/src/Controls/ViewModels/MainControlViewModel.cs b/src/Controls/ViewModels/MainControlViewModel.cs index 0254d8f..8abe745 100644 --- a/src/Controls/ViewModels/MainControlViewModel.cs +++ b/src/Controls/ViewModels/MainControlViewModel.cs @@ -1,8 +1,7 @@ using System; -using System.IO; using Avalonia.Media.Imaging; -using AvaloniaCoreRTDemo.Interfaces; + using ReactiveUI; namespace AvaloniaCoreRTDemo.Controls.ViewModels diff --git a/src/Interfaces/IMainWindow.cs b/src/Interfaces/IMainWindow.cs index a670e2f..36307e2 100644 --- a/src/Interfaces/IMainWindow.cs +++ b/src/Interfaces/IMainWindow.cs @@ -1,6 +1,4 @@ -using Avalonia.Controls; - -namespace AvaloniaCoreRTDemo.Interfaces +namespace AvaloniaCoreRTDemo.Interfaces { public interface IMainWindow { diff --git a/src/Interfaces/IMainWindowState.cs b/src/Interfaces/IMainWindowState.cs index 752cdac..ea25cce 100644 --- a/src/Interfaces/IMainWindowState.cs +++ b/src/Interfaces/IMainWindowState.cs @@ -1,15 +1,16 @@ using System; + using Avalonia.Media.Imaging; namespace AvaloniaCoreRTDemo { - public interface IMainWindowState - { + public interface IMainWindowState + { IBitmap DotNetImage { get; } IBitmap AvaloniaImage { get; } String? Text { get; } void SetUnloadable(); - } + } } diff --git a/src/Utilities.cs b/src/Utilities.cs index 3b740ec..7344219 100644 --- a/src/Utilities.cs +++ b/src/Utilities.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Runtime.InteropServices; + using Avalonia; using Avalonia.Media.Imaging; using Avalonia.Platform; @@ -30,7 +31,7 @@ namespace AvaloniaCoreRTDemo return GetImageFromResources("broken-link.png"); } } - + private static String GetImageFullPath(String fileName) => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName); } diff --git a/src/Windows/AboutWindow.axaml b/src/Windows/AboutWindow.axaml index 58e9b80..e1e5c51 100644 --- a/src/Windows/AboutWindow.axaml +++ b/src/Windows/AboutWindow.axaml @@ -10,7 +10,7 @@ - + diff --git a/src/Windows/AboutWindow.axaml.cs b/src/Windows/AboutWindow.axaml.cs index e1b7aa0..acb023e 100644 --- a/src/Windows/AboutWindow.axaml.cs +++ b/src/Windows/AboutWindow.axaml.cs @@ -1,4 +1,5 @@ using System; + using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index 3c56369..1851b1a 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -1,10 +1,8 @@ -using System; using Avalonia; 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.Windows.ViewModels; @@ -14,7 +12,7 @@ namespace AvaloniaCoreRTDemo.Windows { private readonly Application? _app = App.Current; - public MainWindow() : this(default) { } + public MainWindow() : this(default) { } public MainWindow(IMainWindow? window) { this.InitializeComponent(window); diff --git a/src/Windows/ViewModels/AboutViewModel.cs b/src/Windows/ViewModels/AboutViewModel.cs index e43bd95..2d88481 100644 --- a/src/Windows/ViewModels/AboutViewModel.cs +++ b/src/Windows/ViewModels/AboutViewModel.cs @@ -9,10 +9,10 @@ using ReactiveUI; namespace AvaloniaCoreRTDemo.Windows.ViewModels { internal record SystemDetail(String Key, String Value); - + internal sealed class AboutViewModel : ReactiveObject { - + private readonly IBitmap _computerImage; private readonly Boolean _darkTheme; diff --git a/src/Windows/ViewModels/ApplicationModelBase.cs b/src/Windows/ViewModels/ApplicationModelBase.cs index 09086e3..62c4ee6 100644 --- a/src/Windows/ViewModels/ApplicationModelBase.cs +++ b/src/Windows/ViewModels/ApplicationModelBase.cs @@ -1,5 +1,6 @@ using System; using System.Reactive; + using Avalonia.Controls; using AvaloniaCoreRTDemo.Interfaces; @@ -46,7 +47,7 @@ namespace AvaloniaCoreRTDemo.Windows.ViewModels get => this._fluentDarkEnable; set => this.RaiseAndSetIfChanged(ref this._fluentDarkEnable, value); } - + public ReactiveCommand FileExitCommand { get; } public ApplicationModelBase(IThemeSwitch themeSwitch) diff --git a/src/Windows/ViewModels/MainViewModel.cs b/src/Windows/ViewModels/MainViewModel.cs index bf9d68b..b464ee2 100644 --- a/src/Windows/ViewModels/MainViewModel.cs +++ b/src/Windows/ViewModels/MainViewModel.cs @@ -1,10 +1,6 @@ -using System; -using System.Reactive; +using Avalonia.Controls; -using Avalonia.Controls; -using AvaloniaCoreRTDemo.Controls.ViewModels; using AvaloniaCoreRTDemo.Interfaces; -using ReactiveUI; namespace AvaloniaCoreRTDemo.Windows.ViewModels { From dcc47c332f6665da4bbe4722f74f23bf5c609645 Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:11:58 -0500 Subject: [PATCH 03/13] Window Size * Preserve window size when swapping Fluent and Simple themes. * Simplify test batch files. * Trim output. * Different output type depending on the configuration. --- src/AvaloniaCoreRTDemo.csproj | 19 +++++++++++++------ src/Controls/MainControl.axaml.cs | 5 ++--- src/Interfaces/IMainWindow.cs | 9 ++++++++- src/Windows/AboutWindow.axaml.cs | 9 ++++++--- src/Windows/MainWindow.axaml | 2 +- src/Windows/MainWindow.axaml.cs | 19 ++++++++++++++++--- test.cmd | 2 +- test.command | 2 +- test.sh | 2 +- 9 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj index 5a9bdfb..7de1ab9 100644 --- a/src/AvaloniaCoreRTDemo.csproj +++ b/src/AvaloniaCoreRTDemo.csproj @@ -2,23 +2,29 @@ - WinExe + WinExe + Exe net7.0 - x64 Assets/app.ico true - true enable + true + true + true + + + true true true - + link + false - false + false true true @@ -37,6 +43,7 @@ PreserveNewest PreserveNewest + @@ -49,7 +56,7 @@ - + diff --git a/src/Controls/MainControl.axaml.cs b/src/Controls/MainControl.axaml.cs index c3cde67..52aa012 100644 --- a/src/Controls/MainControl.axaml.cs +++ b/src/Controls/MainControl.axaml.cs @@ -18,10 +18,9 @@ namespace AvaloniaCoreRTDemo.Controls this.DataContext = new MainControlViewModel(); } - public void Reload(IMainWindowState? model) + public void Reload(IMainWindowState model) { - if (model is not null) - this.DataContext = new MainControlViewModel(model); + this.DataContext = new MainControlViewModel(model); } } } diff --git a/src/Interfaces/IMainWindow.cs b/src/Interfaces/IMainWindow.cs index 36307e2..065ef7d 100644 --- a/src/Interfaces/IMainWindow.cs +++ b/src/Interfaces/IMainWindow.cs @@ -1,8 +1,15 @@ -namespace AvaloniaCoreRTDemo.Interfaces +using Avalonia; +using Avalonia.Controls; + +namespace AvaloniaCoreRTDemo.Interfaces { public interface IMainWindow { IThemeSwitch ThemeSwitch { get; } IMainWindowState Model { get; } + PixelPoint Position { get; } + Size ClientSize { get; } + Size? FrameSize { get; } + WindowState State { get; } } } diff --git a/src/Windows/AboutWindow.axaml.cs b/src/Windows/AboutWindow.axaml.cs index acb023e..2676011 100644 --- a/src/Windows/AboutWindow.axaml.cs +++ b/src/Windows/AboutWindow.axaml.cs @@ -10,20 +10,23 @@ namespace AvaloniaCoreRTDemo.Windows { public sealed partial class AboutWindow : Window { + private readonly Boolean _darkTheme; + public AboutWindow() : this(false) { } public AboutWindow(Boolean darkTheme) { - this.InitializeComponent(darkTheme); + this._darkTheme = darkTheme; + this.InitializeComponent(); #if DEBUG this.AttachDevTools(); #endif } - private void InitializeComponent(Boolean darkTheme = default) + private void InitializeComponent() { AvaloniaXamlLoader.Load(this); - this.DataContext = new AboutViewModel(darkTheme); + this.DataContext = new AboutViewModel(this._darkTheme); } } } diff --git a/src/Windows/MainWindow.axaml b/src/Windows/MainWindow.axaml index 4db5a61..3977e9b 100644 --- a/src/Windows/MainWindow.axaml +++ b/src/Windows/MainWindow.axaml @@ -7,7 +7,7 @@ x:DataType="viewModels1:ApplicationModelBase"> - + diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index 1851b1a..3e1bd4a 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -12,6 +12,8 @@ namespace AvaloniaCoreRTDemo.Windows { private readonly Application? _app = App.Current; + private MainControl MainControl => this.GetControl("MainControl"); + public MainWindow() : this(default) { } public MainWindow(IMainWindow? window) { @@ -21,14 +23,25 @@ namespace AvaloniaCoreRTDemo.Windows #endif } - IThemeSwitch IMainWindow.ThemeSwitch => (this._app as IThemeSwitch)!; - IMainWindowState IMainWindow.Model => (this.GetControl("mainControl")!.DataContext as IMainWindowState)!; + IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)this._app!; + IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainControl.DataContext!; + PixelPoint IMainWindow.Position => this.Position; + Size IMainWindow.ClientSize => this.ClientSize; + Size? IMainWindow.FrameSize => this.FrameSize; + WindowState IMainWindow.State => this.WindowState; private void InitializeComponent(IMainWindow? window) { AvaloniaXamlLoader.Load(this); this.DataContext = new MainViewModel(this); - this.GetControl("mainControl").Reload(window?.Model); + if(window is not null) + { + this.MainControl.Reload(window.Model); + this.WindowState = window.State; + this.Position = window.Position; + this.FrameSize = window.FrameSize; + this.ClientSize = window.ClientSize; + } } } } diff --git a/test.cmd b/test.cmd index c9bf3b9..90ebc8d 100644 --- a/test.cmd +++ b/test.cmd @@ -1,2 +1,2 @@ del src\packages.lock.json -dotnet publish -r win-x64 -c release /p:RestoreLockedMode=true /p:TrimLink=true --self-contained \ No newline at end of file +dotnet publish -r win-x64 -c Release /p:RestoreLockedMode=true \ No newline at end of file diff --git a/test.command b/test.command index 674b2ba..a81ffe8 100755 --- a/test.command +++ b/test.command @@ -4,7 +4,7 @@ if [ -d "$dir" ]; then cd "$dir" fi rm -f src/packages.lock.json -dotnet publish -r osx-x64 -c release /p:RestoreLockedMode=true -t:BundleApp /p:TrimLink=true --self-contained +dotnet publish -r osx-x64 -c Release /p:RestoreLockedMode=true -t:BundleApp rm -rf src/bin/x64/Release/net7.0/osx-x64/publish/Assets/ rm -rf src/bin/x64/Release/net7.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/Assets/ rm src/bin/x64/Release/net7.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo.dwarf \ No newline at end of file diff --git a/test.sh b/test.sh index cefc25d..3fb1357 100644 --- a/test.sh +++ b/test.sh @@ -1,6 +1,6 @@ #!/bin/bash rm -f src/packages.lock.json -dotnet publish -r linux-x64 -c release /p:RestoreLockedMode=true /p:TrimLink=true --self-contained +dotnet publish -r linux-x64 -c Release /p:RestoreLockedMode=true cd src/bin/x64/Release/net7.0/linux-x64/publish cp AvaloniaCoreRTDemo AvaloniaCoreRTDemo.bin strip AvaloniaCoreRTDemo.bin From 53a2de07e79a38e5124d2d298d77044114e79232 Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:19:36 -0500 Subject: [PATCH 04/13] Solution file Fix --- AvaloniaCoreRTDemo.sln | 12 ++++++------ README.md | 4 +--- src/Windows/MainWindow.axaml.cs | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/AvaloniaCoreRTDemo.sln b/AvaloniaCoreRTDemo.sln index 33fc22d..29985ad 100644 --- a/AvaloniaCoreRTDemo.sln +++ b/AvaloniaCoreRTDemo.sln @@ -7,14 +7,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AvaloniaCoreRTDemo", "src\A EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|x64.ActiveCfg = Debug|x64 - {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|x64.Build.0 = Debug|x64 - {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.ActiveCfg = Release|x64 - {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|x64.Build.0 = Release|x64 + {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {41A52A04-F7D8-4981-9546-DB020E54851D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {41A52A04-F7D8-4981-9546-DB020E54851D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index d284705..f349479 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This project is tested only under Windows, and this readme assumes you are using * Any supported 64-bit edition of Windows. NativeAOT requires 64-bit Windows and produces only 64-bit Windows apps. * Visual Studio. VS 2022 Community is free for personal use. Get if from [here](https://visualstudio.microsoft.com). When installing Visual Studio, select *.NET desktop development* and *Desktop development with C++* workloads. To generate native code, NativeAOT requires the native C++ toolchain and Windows SDK. This configuration ensures you have them. -* .Net 6.0 SDK. Download it from [here](https://dotnet.microsoft.com/download/dotnet/6.0). Note: Make sure that you download and install the *SDK*. The runtime is not enough for building apps. +* .Net 7.0 SDK. Download it from [here](https://dotnet.microsoft.com/download/dotnet/7.0). Note: Make sure that you download and install the *SDK*. The runtime is not enough for building apps. * Git. Install [Git for Windows](https://git-scm.com/download/win). ## Getting started @@ -34,8 +34,6 @@ We are ready - In your terminal, navigate to `src\bin\Release\net6.0\win-x64\pub Feel free to use this sample as a base for your projects. -When developing, keep in mind that Avalonia uses Reflection extensively. NativeAOT, being an AOT compiler, needs your help to get reflection right. Refer to `rd.xml` file in the solution. In it, you describe all assemblies and types which your app would potentially reflect over. For more information, see [Reflection in AOT mode](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/reflection-in-aot-mode.md) - This project is configured to help you debug issues with publishing. Before publishing, check the CSPROJ file and modify the various Ilc* properties according to [Optimizing programs targeting Native AOT](https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/optimizing.md) document. ## Artifact test diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index 3e1bd4a..6c1f4ae 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -34,7 +34,7 @@ namespace AvaloniaCoreRTDemo.Windows { AvaloniaXamlLoader.Load(this); this.DataContext = new MainViewModel(this); - if(window is not null) + if (window is not null) { this.MainControl.Reload(window.Model); this.WindowState = window.State; From bb42d30511a90e1eaf5a7f7db3b4eb86b8059b7b Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:33:19 -0500 Subject: [PATCH 05/13] Test bash fix --- test.command | 6 +++--- test.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test.command b/test.command index a81ffe8..46a3a1d 100755 --- a/test.command +++ b/test.command @@ -5,6 +5,6 @@ if [ -d "$dir" ]; then fi rm -f src/packages.lock.json dotnet publish -r osx-x64 -c Release /p:RestoreLockedMode=true -t:BundleApp -rm -rf src/bin/x64/Release/net7.0/osx-x64/publish/Assets/ -rm -rf src/bin/x64/Release/net7.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/Assets/ -rm src/bin/x64/Release/net7.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo.dwarf \ No newline at end of file +rm -rf src/bin/Release/net7.0/osx-x64/publish/Assets/ +rm -rf src/bin/Release/net7.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/Assets/ +rm src/bin/Release/net7.0/osx-x64/publish/AvaloniaCoreRTDemo.app/Contents/MacOS/AvaloniaCoreRTDemo.dwarf \ No newline at end of file diff --git a/test.sh b/test.sh index 3fb1357..620d9b4 100644 --- a/test.sh +++ b/test.sh @@ -1,6 +1,6 @@ #!/bin/bash rm -f src/packages.lock.json dotnet publish -r linux-x64 -c Release /p:RestoreLockedMode=true -cd src/bin/x64/Release/net7.0/linux-x64/publish +cd src/bin/Release/net7.0/linux-x64/publish cp AvaloniaCoreRTDemo AvaloniaCoreRTDemo.bin strip AvaloniaCoreRTDemo.bin From ffcfefa0659e5f0c0c3589c07be144f34bcccea9 Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:37:09 -0500 Subject: [PATCH 06/13] Strip only for release --- src/AvaloniaCoreRTDemo.csproj | 2 +- test.sh | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/AvaloniaCoreRTDemo.csproj b/src/AvaloniaCoreRTDemo.csproj index 7de1ab9..637fed2 100644 --- a/src/AvaloniaCoreRTDemo.csproj +++ b/src/AvaloniaCoreRTDemo.csproj @@ -26,7 +26,7 @@ false false true - true + true diff --git a/test.sh b/test.sh index 620d9b4..6a03349 100644 --- a/test.sh +++ b/test.sh @@ -3,4 +3,3 @@ rm -f src/packages.lock.json dotnet publish -r linux-x64 -c Release /p:RestoreLockedMode=true cd src/bin/Release/net7.0/linux-x64/publish cp AvaloniaCoreRTDemo AvaloniaCoreRTDemo.bin -strip AvaloniaCoreRTDemo.bin From cc5c97e1d020b321f0abc866e1b9ab1fbf59efbc Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:42:06 -0500 Subject: [PATCH 07/13] Update dotnet.yml --- .github/workflows/dotnet.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index df9cf82..d6fbfde 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -25,9 +25,9 @@ jobs: with: name: Linux-Artifact path: | - ./src/bin/x64/Release/net7.0/linux-x64/publish/*.bin - ./src/bin/x64/Release/net7.0/linux-x64/publish/*.so - ./src/bin/x64/Release/net7.0/linux-x64/publish/*.png + ./src/bin/Release/net7.0/linux-x64/publish/*.bin + ./src/bin/Release/net7.0/linux-x64/publish/*.so + ./src/bin/Release/net7.0/linux-x64/publish/*.png build-on-windows: runs-on: windows-latest steps: @@ -42,9 +42,9 @@ jobs: with: name: Windows-Artifact path: | - .\src\bin\x64\Release\net7.0\win-x64\publish\*.exe - .\src\bin\x64\Release\net7.0\win-x64\publish\*.dll - .\src\bin\x64\Release\net7.0\win-x64\publish\*.png + .\src\bin\Release\net7.0\win-x64\publish\*.exe + .\src\bin\Release\net7.0\win-x64\publish\*.dll + .\src\bin\Release\net7.0\win-x64\publish\*.png build-on-macos: runs-on: macos-latest steps: @@ -57,7 +57,7 @@ jobs: run: | sudo chmod +x ./test.command ./test.command - cd ./src/bin/x64/Release/net7.0/osx-x64/publish + cd ./src/bin/Release/net7.0/osx-x64/publish zip -r -0 macOS-Artifact.zip *.app mv *.zip ../../../../../../../. - uses: actions/upload-artifact@v2 From 15ede9b17acb0c980e72e29e43c2deab4d7949be Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 10 Feb 2023 13:48:21 -0500 Subject: [PATCH 08/13] Update dotnet.yml Fixes for macOS artifact publish --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index d6fbfde..a35efa0 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -59,7 +59,7 @@ jobs: ./test.command cd ./src/bin/Release/net7.0/osx-x64/publish zip -r -0 macOS-Artifact.zip *.app - mv *.zip ../../../../../../../. + mv *.zip ../../../../../../. - uses: actions/upload-artifact@v2 with: name: macOS-Artifact From 8caed1f4d28b317998b38fc12a42d073c8375c6e Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Sat, 11 Feb 2023 00:41:41 -0500 Subject: [PATCH 09/13] More fixes --- src/App.axaml.cs | 2 ++ src/Windows/MainWindow.axaml.cs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/App.axaml.cs b/src/App.axaml.cs index 0cd350c..8cf244d 100644 --- a/src/App.axaml.cs +++ b/src/App.axaml.cs @@ -100,6 +100,8 @@ namespace AvaloniaCoreRTDemo desktop.MainWindow = newWindow; this.DataContext = newWindow.DataContext; + + oldWindow.Hide(); newWindow.Show(); oldWindow.Close(); } diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index 6c1f4ae..4df6271 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -37,6 +37,7 @@ namespace AvaloniaCoreRTDemo.Windows 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; From c345223fdce476b5f72084d888be80de45f555ae Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Sat, 11 Feb 2023 11:35:53 -0500 Subject: [PATCH 10/13] Fix window position on macOS --- src/Utilities.cs | 12 +++++ src/Windows/MainWindow.axaml.cs | 90 ++++++++++++++++----------------- 2 files changed, 57 insertions(+), 45 deletions(-) diff --git a/src/Utilities.cs b/src/Utilities.cs index 7344219..e51dcb7 100644 --- a/src/Utilities.cs +++ b/src/Utilities.cs @@ -3,6 +3,7 @@ using System.IO; using System.Runtime.InteropServices; using Avalonia; +using Avalonia.Controls; using Avalonia.Media.Imaging; using Avalonia.Platform; @@ -20,6 +21,17 @@ namespace AvaloniaCoreRTDemo return new Bitmap(assetStream); } + public static PixelPoint GetWindowPosition(Window window) + { + if (!IsOSX || !window.FrameSize.HasValue) + return window.Position; + else + { + Int32 yOffset = (Int32)(window.FrameSize.Value.Height - window.ClientSize.Height); + return new(window.Position.X, window.Position.Y + yOffset); + } + } + public static Bitmap GetImageFromFile(String path) { try diff --git a/src/Windows/MainWindow.axaml.cs b/src/Windows/MainWindow.axaml.cs index 4df6271..fd51056 100644 --- a/src/Windows/MainWindow.axaml.cs +++ b/src/Windows/MainWindow.axaml.cs @@ -1,48 +1,48 @@ -using Avalonia; -using Avalonia.Controls; +using Avalonia; +using Avalonia.Controls; using Avalonia.Markup.Xaml; -using AvaloniaCoreRTDemo.Controls; -using AvaloniaCoreRTDemo.Interfaces; -using AvaloniaCoreRTDemo.Windows.ViewModels; - -namespace AvaloniaCoreRTDemo.Windows -{ - public sealed partial class MainWindow : Window, IMainWindow - { - private readonly Application? _app = App.Current; - - private MainControl MainControl => this.GetControl("MainControl"); - +using AvaloniaCoreRTDemo.Controls; +using AvaloniaCoreRTDemo.Interfaces; +using AvaloniaCoreRTDemo.Windows.ViewModels; + +namespace AvaloniaCoreRTDemo.Windows +{ + public sealed partial class MainWindow : Window, IMainWindow + { + private readonly Application? _app = App.Current; + + private MainControl MainControl => this.GetControl("MainControl"); + public MainWindow() : this(default) { } - public MainWindow(IMainWindow? window) - { - this.InitializeComponent(window); -#if DEBUG - this.AttachDevTools(); -#endif - } - - IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)this._app!; - IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainControl.DataContext!; - PixelPoint IMainWindow.Position => this.Position; - Size IMainWindow.ClientSize => this.ClientSize; - Size? IMainWindow.FrameSize => this.FrameSize; - WindowState IMainWindow.State => this.WindowState; - - private void InitializeComponent(IMainWindow? window) - { - AvaloniaXamlLoader.Load(this); - this.DataContext = new MainViewModel(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; - } - } - } -} + public MainWindow(IMainWindow? window) + { + this.InitializeComponent(window); +#if DEBUG + this.AttachDevTools(); +#endif + } + + IThemeSwitch IMainWindow.ThemeSwitch => (IThemeSwitch)this._app!; + IMainWindowState IMainWindow.Model => (IMainWindowState)this.MainControl.DataContext!; + PixelPoint IMainWindow.Position => Utilities.GetWindowPosition(this); + Size IMainWindow.ClientSize => this.ClientSize; + Size? IMainWindow.FrameSize => this.FrameSize; + WindowState IMainWindow.State => this.WindowState; + + private void InitializeComponent(IMainWindow? window) + { + AvaloniaXamlLoader.Load(this); + this.DataContext = new MainViewModel(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; + } + } + } +} From ad13e8ca2988dda03c053358b9751d00f0f467f8 Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 17 Feb 2023 08:15:09 -0500 Subject: [PATCH 11/13] Restore nuget.config --- src/nuget.config | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/nuget.config diff --git a/src/nuget.config b/src/nuget.config new file mode 100644 index 0000000..3d11832 --- /dev/null +++ b/src/nuget.config @@ -0,0 +1,7 @@ + + + + + + + From a3ad58c937118f679916a1412fa3a2fd061c1b7e Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 17 Feb 2023 08:35:39 -0500 Subject: [PATCH 12/13] Restore SystemDetail record --- src/Windows/ViewModels/AboutViewModel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Windows/ViewModels/AboutViewModel.cs b/src/Windows/ViewModels/AboutViewModel.cs index 2d88481..2e72d49 100644 --- a/src/Windows/ViewModels/AboutViewModel.cs +++ b/src/Windows/ViewModels/AboutViewModel.cs @@ -8,7 +8,7 @@ using ReactiveUI; namespace AvaloniaCoreRTDemo.Windows.ViewModels { - internal record SystemDetail(String Key, String Value); + internal record SystemDetail(string Key, string Value); internal sealed class AboutViewModel : ReactiveObject { From 46bb647934eb0561a8db6c92305e124cf165f3f4 Mon Sep 17 00:00:00 2001 From: Joseph Moreno <44370115+josephmoresena@users.noreply.github.com> Date: Fri, 17 Feb 2023 17:36:22 -0500 Subject: [PATCH 13/13] Comment out Avalonia source in nuget.config --- src/nuget.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nuget.config b/src/nuget.config index 3d11832..72fcfd7 100644 --- a/src/nuget.config +++ b/src/nuget.config @@ -1,7 +1,7 @@ - +