diff --git a/README.adoc b/README.adoc index ab83153..88d2cd0 100644 --- a/README.adoc +++ b/README.adoc @@ -1,4 +1,4 @@ -= Avalonia image:_docs/_Assets/Logo.svg[link=https://www.avaloniaui.net] Samples += Avalonia image:_docs/_Assets/Logo.svg[link=https://www.avaloniaui.net] Samples ifndef::env-github[] :toc: left endif::[] @@ -108,6 +108,20 @@ Each sample is tagged with its difficulty. The degree of difficulty describes ho |=== +[#_desktop_integration_samples] +=== 🪟 DesktopIntegration-Samples + +[cols="25h,25,50"] +|=== +| Sample | Difficulty | Buzz-Words + +| link:src/Avalonia.Samples/DesktopIntegration/TrayIcon[Tray Icon Sample] +| 🐣 Beginner +| TrayIcon, ReactiveUI, Binding + +|=== + + [#_drawing_samples] === ✒️ Drawing-Samples @@ -270,7 +284,7 @@ IMPORTANT: If you change the difficulty or the buzz-words, remember to also upda .. link:/_docs/Markdown-Template/[Markdown-Template]: If you prefer not to use AsciiDoc, you can instead use the Markdown-template. // Comment this in for next year's Hacktoberfest -//// +//// === 🎃 Hacktoberfest 2023 We are participating in https://hacktoberfest.com[[Hacktoberfest 2023\]]. If you submit a valid pull request within this month, we will add the `HACKTOBERFEST-ACCEPTED` label to your PR. Read more about it and how to participate https://hacktoberfest.com/participation/[[here\]]. @@ -281,7 +295,7 @@ Valid PRs are:: - Improving an existing sample - Doing an overall spell-check (Not just changing a random word!) -WARNING: Spam or invalid PRs will be marked as invalid. If you are unsure if your PR will be accepted for Hacktoberfest, you can ask us here or in the image:https://raw.githubusercontent.com/Patrolavia/telegram-badge/master/chat.svg[link=https://t.me/Avalonia]. +WARNING: Spam or invalid PRs will be marked as invalid. If you are unsure if your PR will be accepted for Hacktoberfest, you can ask us here or in the image:https://raw.githubusercontent.com/Patrolavia/telegram-badge/master/chat.svg[link=https://t.me/Avalonia]. 🎃 Happy coding 🎃 //// diff --git a/src/Avalonia.Samples/Avalonia.Samples.sln b/src/Avalonia.Samples/Avalonia.Samples.sln index b668423..d1096a9 100644 --- a/src/Avalonia.Samples/Avalonia.Samples.sln +++ b/src/Avalonia.Samples/Avalonia.Samples.sln @@ -64,6 +64,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SnowflakesControlSample", " EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MusicStore", "CompleteApps\Avalonia.MusicStore\Avalonia.MusicStore.csproj", "{AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesktopIntegration", "DesktopIntegration", "{8A863147-348B-47C4-902B-E132B62BB1C2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrayIcon", "DesktopIntegration\TrayIcon\TrayIcon.csproj", "{EB8D1498-2528-4FE5-B2B0-515293A8880C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -314,6 +318,10 @@ Global {AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}.Release|x64.Build.0 = Release|Any CPU {AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}.Release|x86.ActiveCfg = Release|Any CPU {AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}.Release|x86.Build.0 = Release|Any CPU + {EB8D1498-2528-4FE5-B2B0-515293A8880C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB8D1498-2528-4FE5-B2B0-515293A8880C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB8D1498-2528-4FE5-B2B0-515293A8880C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB8D1498-2528-4FE5-B2B0-515293A8880C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -339,6 +347,7 @@ Global {2B746401-384F-484A-810E-7A65288165E0} = {D02161B3-8242-4BF5-96E9-780465A5023B} {B7B246E1-26F7-4225-A8FC-4344C1D7BA17} = {92C71AA7-E791-40C0-9F3A-2A85880B0439} {AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A} = {50FCF785-BBCF-4AFE-AC72-79EA9E92C43A} + {EB8D1498-2528-4FE5-B2B0-515293A8880C} = {8A863147-348B-47C4-902B-E132B62BB1C2} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C246CAB0-0837-4EE4-A22D-28B3C74930B4} diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml new file mode 100644 index 0000000..5f6e00a --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml.cs b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml.cs new file mode 100644 index 0000000..8443d75 --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml.cs @@ -0,0 +1,27 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; + +namespace TrayIcon +{ + public partial class AboutWindow : Window + { + public AboutWindow() + { + InitializeComponent(); + } + + public void SetActivationMode(ActivationMode mode) + { + switch (mode) + { + case ActivationMode.Click: lblActivationMode.Content = "Activated by clicking"; break; + case ActivationMode.MenuItem: lblActivationMode.Content = "Activated by selecting menu item"; break; + } + } + + void cmdClose_Click(object? sender, RoutedEventArgs e) + { + this.Close(); + } + } +} diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/ActivationMode.cs b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/ActivationMode.cs new file mode 100644 index 0000000..71721ca --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/ActivationMode.cs @@ -0,0 +1,8 @@ +namespace TrayIcon +{ + public enum ActivationMode + { + Click, + MenuItem, + } +} \ No newline at end of file diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml new file mode 100644 index 0000000..2d27cde --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml.cs b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml.cs new file mode 100644 index 0000000..376707e --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml.cs @@ -0,0 +1,68 @@ +using System.Windows.Input; + +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +using CommunityToolkit.Mvvm.Input; + +namespace TrayIcon +{ + public partial class App : Application + { + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public App() + { + DataContext = this; + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + desktop.ShutdownMode = Avalonia.Controls.ShutdownMode.OnExplicitShutdown; + } + + base.OnFrameworkInitializationCompleted(); + } + + [RelayCommand] + public void TrayIconClicked() + { + var window = new AboutWindow(); + + window.SetActivationMode(ActivationMode.Click); + + window.Show(); + } + + [RelayCommand] + public void ShowAboutWindow() + { + var window = new AboutWindow(); + + window.SetActivationMode(ActivationMode.MenuItem); + + window.Show(); + } + + [RelayCommand] + public void ExitApplication() + { + switch (ApplicationLifetime) + { + case IClassicDesktopStyleApplicationLifetime desktopLifetime: + desktopLifetime.TryShutdown(); + break; + case IControlledApplicationLifetime controlledLifetime: + controlledLifetime.Shutdown(); + break; + } + } + } +} + diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.manifest b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.manifest new file mode 100644 index 0000000..bedffa8 --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AssemblyInfo.cs b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AssemblyInfo.cs new file mode 100644 index 0000000..d09de88 --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/AssemblyInfo.cs @@ -0,0 +1 @@ +using System.Runtime.CompilerServices; diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Icon.ico b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Icon.ico new file mode 100644 index 0000000..1c290f2 Binary files /dev/null and b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Icon.ico differ diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Program.cs b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Program.cs new file mode 100644 index 0000000..73bfbe5 --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Program.cs @@ -0,0 +1,27 @@ +using System; + +using Avalonia; + +namespace TrayIcon +{ + class Program + { + [STAThread] + public static void Main(string[] args) + { + Console.WriteLine("Check the system notification area for a new icon"); + + var app = BuildAvaloniaApp(); + + app.StartWithClassicDesktopLifetime(args); + } + + public static AppBuilder BuildAvaloniaApp() + { + return AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); + } + } +} diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/README.md b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/README.md new file mode 100644 index 0000000..3052568 --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/README.md @@ -0,0 +1,9 @@ +# TrayIcon + +Sample application that shows a tray icon. + +![Screenshot of TrayIcon Sample](Screenshot.png "TrayIcon in action") + +* The tray icon must have an associated icon. The icon should be included in the project as an ``. +* This sample sets the `DataContext` for `App` to `this`, which allows the command to be defined in the same class and then bound in the `.axaml` file. Consider using a separate view model in production code. + diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Screenshot.png b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Screenshot.png new file mode 100644 index 0000000..5f64308 Binary files /dev/null and b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/Screenshot.png differ diff --git a/src/Avalonia.Samples/DesktopIntegration/TrayIcon/TrayIcon.csproj b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/TrayIcon.csproj new file mode 100644 index 0000000..6cbcd0b --- /dev/null +++ b/src/Avalonia.Samples/DesktopIntegration/TrayIcon/TrayIcon.csproj @@ -0,0 +1,21 @@ + + + WinExe + net8.0 + enable + true + + + + + + + + + + + + + + +