diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs index 4bb5275f9..be3212805 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/App.axaml.cs @@ -2,6 +2,7 @@ using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using ReactiveUI; +using System.Application.Mvvm; using System.Application.UI.ViewModels; using System.Application.UI.Views; using System.Collections.Generic; @@ -12,7 +13,7 @@ using AvaloniaApplication = Avalonia.Application; namespace System.Application.UI { - public class App : AvaloniaApplication + public class App : AvaloniaApplication, IDisposableHolder { public static App Instance => Current is App app ? app : throw new Exception("Impossible"); @@ -50,9 +51,7 @@ namespace System.Application.UI MessageBoxButton.OK, MessageBoxImage.Warning); } - #region NotifyIcon - var notifyIcon = INotifyIcon.Instance; notifyIcon.ToolTipText = ThisAssembly.AssemblyTrademark; switch (DI.Platform) @@ -88,17 +87,34 @@ namespace System.Application.UI NotifyIconContextMenu.Items = menuItems; notifyIcon.ContextMenu = NotifyIconContextMenu; notifyIcon.Visible = true; - + notifyIcon.Click += NotifyIcon_Click; + notifyIcon.DoubleClick += NotifyIcon_Click; + this.compositeDisposable.Add(() => + { + notifyIcon.IconPath = string.Empty; + }); #endregion desktop.MainWindow = MainWindow; - + desktop.Exit += Desktop_Exit; desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown; } + + base.OnFrameworkInitializationCompleted(); } + private void Desktop_Exit(object? sender, ControlledApplicationLifetimeExitEventArgs e) + { + this.compositeDisposable.Dispose(); + } + + private void NotifyIcon_Click(object? sender, EventArgs e) + { + RestoreMainWindow(); + } + public static async void SetClipboardText(string s) => await Current.Clipboard.SetTextAsync(s); public Window? MainWindow { get; set; } @@ -135,12 +151,30 @@ namespace System.Application.UI /// /// Exits the app by calling Shutdown() on the IClassicDesktopStyleApplicationLifetime. /// - public static void Exit() + public static void Shutdown() { if (Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { desktop.Shutdown(0); } } + /// + /// Exits the app by calling Shutdown() on the IClassicDesktopStyleApplicationLifetime. + /// + public static void Exit() + { + Shutdown(); + } + + #region IDisposable members + public readonly CompositeDisposable compositeDisposable = new CompositeDisposable(); + ICollection IDisposableHolder.CompositeDisposable => this.compositeDisposable; + + void IDisposable.Dispose() + { + this.compositeDisposable.Dispose(); + GC.SuppressFinalize(this); + } + #endregion } } \ No newline at end of file diff --git a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs index fac8d4368..7db73ef44 100644 --- a/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs +++ b/System.Application.SteamTools.Client.Desktop.Avalonia.App/Views/MainWindow.axaml.cs @@ -2,6 +2,7 @@ using Avalonia; using Avalonia.Controls; using Avalonia.Markup.Xaml; using System.Application.UI.ViewModels; +using System.ComponentModel; namespace System.Application.UI.Views { @@ -15,6 +16,13 @@ namespace System.Application.UI.Views #endif } + protected override void OnClosing(CancelEventArgs e) + { + e.Cancel = true; + this.Hide(); + base.OnClosed(e); + } + private void InitializeComponent() { AvaloniaXamlLoader.Load(this); diff --git a/System.Application.SteamTools.Client.Desktop/Mvvm/CompositeDisposable.cs b/System.Application.SteamTools.Client.Desktop/Mvvm/CompositeDisposable.cs index ab147a0b1..66198dbce 100644 --- a/System.Application.SteamTools.Client.Desktop/Mvvm/CompositeDisposable.cs +++ b/System.Application.SteamTools.Client.Desktop/Mvvm/CompositeDisposable.cs @@ -8,7 +8,7 @@ namespace System.Application.Mvvm /// /// 提供用于一次处理多个IDisposable对象的功能 /// - public class CompositeDisposable : IDisposable, ICollection + public class CompositeDisposable : IDisposable, ICollection, IEnumerable, IEnumerable { readonly object _lockObject = new object(); readonly List _targetLists; diff --git a/System.Application.SteamTools.Client.Desktop/Mvvm/IDisposableHolder.cs b/System.Application.SteamTools.Client.Desktop/Mvvm/IDisposableHolder.cs new file mode 100644 index 000000000..c5e11bc48 --- /dev/null +++ b/System.Application.SteamTools.Client.Desktop/Mvvm/IDisposableHolder.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace System.Application.Mvvm +{ + public interface IDisposableHolder : IDisposable + { + ICollection CompositeDisposable { get; } + } +}