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.
+
+
+
+* 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+