Skip to content

Commit 06d28f6

Browse files
timunielogiclrd
andauthored
Fix TrayIconSample (#213)
* Added TrayIcon sample app. * Updated the TrayIcon sample to support activation by clicking on the tray icon (on supported platforms): - Updated AboutWindow.axaml to include a Label indicating how it was activated. Added method SetActivationMode to AboutWindow.axaml. Added enumerated type ActivationMode.cs. - Updated the ShowAboutWindow command handler method in App.axaml.cs to call AboutWindow.SetActivationMode. - Added command ClickedCommand with handler method Clicked to App.axaml.cs. - Updated App.axaml to wire up TrayIcon.Command to ClickedCommand. * Corrected link to the TrayIcon sample in README.adoc. * Added a screenshot of TrayIcon in action and updated TrayIcon/README.md to include it. * Updated AboutWindow.axaml to make the Close button respond to the Escape key (IsCancel="True"). * Updated references to Avalonia NuGet packages in TrayIcon.csproj to the latest release. * Updated Program.cs to write a line to the console telling the user to check for a notification area icon. * Reworked the TrayIcon sample to use [RelayCommand] on handler methods directly instead of ReactiveCommand. Replaced the NuGet reference to Avalonia.ReactiveUI with one to CommunityToolkit.Mvvm. Updated ExitApplication in App.axaml.cs to use TryShutdown instead of Shutdown where possible, and to support IControlledApplicationLifetime if the current lifetime isn't an IClassicDesktopStyleApplicationLifetime. Made the names of the commands in App.axaml/.axaml.cs more descriptive. * Fix sln file --------- Co-authored-by: Jonathan Gilbert <[email protected]>
1 parent 2420c6f commit 06d28f6

File tree

11 files changed

+73
-30
lines changed

11 files changed

+73
-30
lines changed

README.adoc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,18 @@ Each sample is tagged with its difficulty. The degree of difficulty describes ho
119119
120120
|===
121121
122+
=== ✒️ Drawing-Samples
123+
124+
[cols="25h,25,50"]
125+
|===
126+
| Sample | Difficulty | Buzz-Words
127+
128+
| link:src/Avalonia.Samples/DesktopIntegration/TrayIcon[Tray Icon Sample]
129+
| 🐣 Beginner
130+
| TrayIcon, ReactiveUI, Binding
131+
132+
|===
133+
122134
123135
124136
[#_drawing_samples]

src/Avalonia.Samples/Avalonia.Samples.sln

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SnowflakesControlSample", "
6464
EndProject
6565
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.MusicStore", "CompleteApps\Avalonia.MusicStore\Avalonia.MusicStore.csproj", "{AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}"
6666
EndProject
67-
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesktopIntegration", "DesktopIntegration", "{2FBF7E83-2410-43D0-AC59-9292D779674C}"
67+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrayIcon", "DesktopIntegration\TrayIcon\TrayIcon.csproj", "{EB8D1498-2528-4FE5-B2B0-515293A8880C}"
6868
EndProject
69-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrayIcon", "DesktopIntegration\TrayIcon\TrayIcon.csproj", "{D539FEE4-6228-4842-A61D-ABB281254F1A}"
69+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DesktopIntegration", "DesktopIntegration", "{430991E5-C6DB-458F-82D7-E66B64EC7081}"
7070
EndProject
7171
Global
7272
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -318,18 +318,8 @@ Global
318318
{AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}.Release|x64.Build.0 = Release|Any CPU
319319
{AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}.Release|x86.ActiveCfg = Release|Any CPU
320320
{AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A}.Release|x86.Build.0 = Release|Any CPU
321-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
322-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
323-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Debug|x64.ActiveCfg = Debug|Any CPU
324-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Debug|x64.Build.0 = Debug|Any CPU
325-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Debug|x86.ActiveCfg = Debug|Any CPU
326-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Debug|x86.Build.0 = Debug|Any CPU
327-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
328-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Release|Any CPU.Build.0 = Release|Any CPU
329-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Release|x64.ActiveCfg = Release|Any CPU
330-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Release|x64.Build.0 = Release|Any CPU
331-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Release|x86.ActiveCfg = Release|Any CPU
332-
{D539FEE4-6228-4842-A61D-ABB281254F1A}.Release|x86.Build.0 = Release|Any CPU
321+
{EB8D1498-2528-4FE5-B2B0-515293A8880C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
322+
{EB8D1498-2528-4FE5-B2B0-515293A8880C}.Debug|Any CPU.Build.0 = Debug|Any CPU
333323
EndGlobalSection
334324
GlobalSection(SolutionProperties) = preSolution
335325
HideSolutionNode = FALSE
@@ -355,7 +345,7 @@ Global
355345
{2B746401-384F-484A-810E-7A65288165E0} = {D02161B3-8242-4BF5-96E9-780465A5023B}
356346
{B7B246E1-26F7-4225-A8FC-4344C1D7BA17} = {92C71AA7-E791-40C0-9F3A-2A85880B0439}
357347
{AA9BFD5E-9F4E-46CB-90FD-A4BAB9878A4A} = {50FCF785-BBCF-4AFE-AC72-79EA9E92C43A}
358-
{D539FEE4-6228-4842-A61D-ABB281254F1A} = {2FBF7E83-2410-43D0-AC59-9292D779674C}
348+
{EB8D1498-2528-4FE5-B2B0-515293A8880C} = {430991E5-C6DB-458F-82D7-E66B64EC7081}
359349
EndGlobalSection
360350
GlobalSection(ExtensibilityGlobals) = postSolution
361351
SolutionGuid = {C246CAB0-0837-4EE4-A22D-28B3C74930B4}

src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Width="800" Height="400" WindowState="Normal" WindowStartupLocation="CenterScreen">
66
<Grid>
77
<Grid.RowDefinitions>
8+
<RowDefinition Height="*" />
89
<RowDefinition Height="*" />
910
<RowDefinition Height="Auto" />
1011
</Grid.RowDefinitions>
@@ -13,6 +14,10 @@
1314
Avalonia Tray Icon Sample
1415
</Label>
1516

16-
<Button Name="cmdClose" Click="cmdClose_Click" Grid.Row="1" Margin="30" HorizontalAlignment="Center">_Close</Button>
17+
<Label Name="lblActivationMode" Grid.Row="1" FontSize="16" HorizontalContentAlignment="Center" VerticalContentAlignment="Center">
18+
Activated by...
19+
</Label>
20+
21+
<Button Name="cmdClose" Click="cmdClose_Click" IsCancel="True" Grid.Row="2" Margin="30" HorizontalAlignment="Center">_Close</Button>
1722
</Grid>
1823
</Window>

src/Avalonia.Samples/DesktopIntegration/TrayIcon/AboutWindow.axaml.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ public AboutWindow()
1010
InitializeComponent();
1111
}
1212

13+
public void SetActivationMode(ActivationMode mode)
14+
{
15+
switch (mode)
16+
{
17+
case ActivationMode.Click: lblActivationMode.Content = "Activated by clicking"; break;
18+
case ActivationMode.MenuItem: lblActivationMode.Content = "Activated by selecting menu item"; break;
19+
}
20+
}
21+
1322
void cmdClose_Click(object? sender, RoutedEventArgs e)
1423
{
1524
this.Close();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace TrayIcon
2+
{
3+
public enum ActivationMode
4+
{
5+
Click,
6+
MenuItem,
7+
}
8+
}

src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
<TrayIcon.Icons>
1313
<TrayIcons>
14-
<TrayIcon Icon="Icon.ico" ToolTipText="TrayIcon Sample">
14+
<TrayIcon Icon="Icon.ico" ToolTipText="TrayIcon Sample" Command="{Binding TrayIconClickedCommand}">
1515
<TrayIcon.Menu>
1616
<NativeMenu>
17-
<NativeMenuItem Header="_About" Command="{Binding ShowAboutCommand}" />
17+
<NativeMenuItem Header="_About" Command="{Binding ShowAboutWindowCommand}" />
1818
<NativeMenuItemSeparator />
1919
<NativeMenuItem Header="E_xit" Command="{Binding ExitApplicationCommand}" />
2020
</NativeMenu>

src/Avalonia.Samples/DesktopIntegration/TrayIcon/App.axaml.cs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
using System.Windows.Input;
2+
13
using Avalonia;
24
using Avalonia.Controls.ApplicationLifetimes;
35
using Avalonia.Markup.Xaml;
6+
47
using CommunityToolkit.Mvvm.Input;
58

69
namespace TrayIcon
@@ -26,25 +29,38 @@ public override void OnFrameworkInitializationCompleted()
2629

2730
base.OnFrameworkInitializationCompleted();
2831
}
29-
32+
3033
[RelayCommand]
31-
public void ShowAbout()
34+
public void TrayIconClicked()
3235
{
3336
var window = new AboutWindow();
3437

38+
window.SetActivationMode(ActivationMode.Click);
39+
3540
window.Show();
3641
}
3742

3843
[RelayCommand]
39-
void ExitApplication()
44+
public void ShowAboutWindow()
4045
{
41-
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktopLifetime)
42-
{
43-
desktopLifetime.TryShutdown();
44-
}
45-
else if (ApplicationLifetime is IControlledApplicationLifetime controlledLifetime)
46+
var window = new AboutWindow();
47+
48+
window.SetActivationMode(ActivationMode.MenuItem);
49+
50+
window.Show();
51+
}
52+
53+
[RelayCommand]
54+
public void ExitApplication()
55+
{
56+
switch (ApplicationLifetime)
4657
{
47-
controlledLifetime.Shutdown();
58+
case IClassicDesktopStyleApplicationLifetime desktopLifetime:
59+
desktopLifetime.TryShutdown();
60+
break;
61+
case IControlledApplicationLifetime controlledLifetime:
62+
controlledLifetime.Shutdown();
63+
break;
4864
}
4965
}
5066
}

src/Avalonia.Samples/DesktopIntegration/TrayIcon/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class Program
99
[STAThread]
1010
public static void Main(string[] args)
1111
{
12+
Console.WriteLine("Check the system notification area for a new icon");
13+
1214
var app = BuildAvaloniaApp();
1315

1416
app.StartWithClassicDesktopLifetime(args);

src/Avalonia.Samples/DesktopIntegration/TrayIcon/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
Sample application that shows a tray icon.
44

5+
![Screenshot of TrayIcon Sample](Screenshot.png "TrayIcon in action")
6+
57
* The tray icon must have an associated icon. The icon should be included in the project as an `<AvaloniaResource>`.
68
* 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.
79

17.5 KB
Loading

0 commit comments

Comments
 (0)