Skip to content

Commit ee013f3

Browse files
committed
feat: improve ToastNotification
1 parent 7a06c69 commit ee013f3

10 files changed

+172
-16
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// ReSharper disable once CheckNamespace
2+
namespace Atc.Wpf.Controls;
3+
4+
public static class ToastNotificationContentExtensions
5+
{
6+
public static ToastNotificationContent ToToastNotificationContent(
7+
this ToastNotificationMessage message)
8+
{
9+
ArgumentNullException.ThrowIfNull(message);
10+
11+
return new ToastNotificationContent(
12+
message.ToastNotificationType,
13+
message.Title,
14+
message.Message);
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// ReSharper disable once CheckNamespace
2+
namespace Atc.Wpf.Controls;
3+
4+
public static class ToastNotificationMessageExtensions
5+
{
6+
public static ApplicationEventEntry ToApplicationEventEntry(
7+
this ToastNotificationMessage message)
8+
{
9+
ArgumentNullException.ThrowIfNull(message);
10+
11+
return new ApplicationEventEntry(
12+
message.ToastNotificationType.ToLogCategoryType(),
13+
message.Title,
14+
message.Message);
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// ReSharper disable once CheckNamespace
2+
namespace Atc.Wpf.Controls;
3+
4+
public static class ToastNotificationTypeExtensions
5+
{
6+
public static LogCategoryType ToLogCategoryType(
7+
this ToastNotificationType toastNotificationType)
8+
{
9+
return toastNotificationType switch
10+
{
11+
ToastNotificationType.Information or ToastNotificationType.Success => LogCategoryType.Information,
12+
ToastNotificationType.Warning => LogCategoryType.Warning,
13+
ToastNotificationType.Error => LogCategoryType.Error,
14+
_ => throw new SwitchCaseDefaultException(toastNotificationType),
15+
};
16+
}
17+
}

src/Atc.Wpf.Controls/GlobalUsings.cs

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
global using Atc.Wpf.Controls.LabelControls.Writers;
5454
global using Atc.Wpf.Controls.Layouts.Grid.Internal;
5555
global using Atc.Wpf.Controls.Media;
56+
global using Atc.Wpf.Controls.Monitoring;
57+
global using Atc.Wpf.Controls.Notifications;
58+
global using Atc.Wpf.Controls.Notifications.Messages;
5659
global using Atc.Wpf.Controls.Options;
5760
global using Atc.Wpf.Controls.Progressing.Internal;
5861
global using Atc.Wpf.Controls.Resources;

src/Atc.Wpf.Controls/Monitoring/ApplicationMonitorViewModel.cs

+36
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public sealed class ApplicationMonitorViewModel : ViewModelBase
99
private bool autoScroll;
1010
private ApplicationEventEntry? selectedEntry;
1111
private ListSortDirection sortDirection;
12+
private bool listenOnToastNotificationMessage;
1213

1314
public ApplicationMonitorViewModel()
1415
{
@@ -117,6 +118,30 @@ public string MatchOnText
117118
}
118119
}
119120

121+
public bool ListenOnToastNotificationMessage
122+
{
123+
get => listenOnToastNotificationMessage;
124+
set
125+
{
126+
if (value == listenOnToastNotificationMessage)
127+
{
128+
return;
129+
}
130+
131+
listenOnToastNotificationMessage = value;
132+
RaisePropertyChanged();
133+
134+
if (listenOnToastNotificationMessage)
135+
{
136+
MessengerInstance.Register<ToastNotificationMessage>(this, OnToastNotificationMessageHandler);
137+
}
138+
else
139+
{
140+
MessengerInstance.UnRegister<ToastNotificationMessage>(this, OnToastNotificationMessageHandler);
141+
}
142+
}
143+
}
144+
120145
public void AddEntry(
121146
ApplicationEventEntry entry)
122147
{
@@ -147,6 +172,17 @@ private void OnApplicationEventEntryHandler(
147172
ApplicationEventEntry entry)
148173
=> AddEntry(entry);
149174

175+
private void OnToastNotificationMessageHandler(
176+
ToastNotificationMessage message)
177+
{
178+
if (!ListenOnToastNotificationMessage)
179+
{
180+
return;
181+
}
182+
183+
AddEntry(message.ToApplicationEventEntry());
184+
}
185+
150186
private void ClearCommandHandler()
151187
{
152188
lock (SyncLock)

src/Atc.Wpf.Controls/Notifications/IToastNotificationManager.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ public interface IToastNotificationManager
44
{
55
void Show(
66
bool useDesktop,
7-
object content,
7+
UserControl content,
88
string areaName = "",
99
TimeSpan? expirationTime = null,
1010
Action? onClick = null,

src/Atc.Wpf.Controls/Notifications/ToastNotificationArea.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@ public override void OnApplyTemplate()
4949

5050
[SuppressMessage("AsyncUsage", "AsyncFixer03:Fire-and-forget async-void methods or delegates", Justification = "OK - Need 'async void' and not 'async Task'")]
5151
[SuppressMessage("Major Bug", "S3168:\"async\" methods should not return \"void\"", Justification = "OK - Need 'async void' and not 'async Task'")]
52+
[SuppressMessage("ReSharper", "AsyncVoidMethod", Justification = "OK - Need 'async void' and not 'async Task'")]
5253
public async void Show(
53-
object content,
54+
ContentControl contentControl,
5455
TimeSpan expirationTime,
5556
Action? onClick,
5657
Action? onClose)
5758
{
5859
var toastNotification = new ToastNotification
5960
{
60-
Content = content,
61+
Content = contentControl,
6162
};
6263

6364
toastNotification.MouseLeftButtonDown += (sender, _) =>
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
namespace Atc.Wpf.Controls.Notifications;
22

3-
public record ToastNotificationContent(
4-
ToastNotificationType Type,
5-
string Title,
6-
string Message);
3+
public class ToastNotificationContent(
4+
ToastNotificationType type,
5+
string title,
6+
string message)
7+
: UserControl
8+
{
9+
public ToastNotificationType Type { get; init; } = type;
10+
11+
public string Title { get; init; } = title;
12+
13+
public string Message { get; init; } = message;
14+
15+
public void Deconstruct(
16+
out ToastNotificationType type,
17+
out string title,
18+
out string message)
19+
{
20+
type = Type;
21+
title = Title;
22+
message = Message;
23+
}
24+
}

src/Atc.Wpf.Controls/Notifications/ToastNotificationManager.cs

+53-7
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,50 @@ namespace Atc.Wpf.Controls.Notifications;
33
public sealed class ToastNotificationManager : IToastNotificationManager
44
{
55
private readonly Dispatcher dispatcher;
6-
private static readonly List<ToastNotificationArea> Areas = new();
6+
private static readonly List<ToastNotificationArea> Areas = [];
77
private static ToastNotificationsOverlayWindow? window;
88

9-
public ToastNotificationManager(Dispatcher? dispatcher = null)
9+
public ToastNotificationManager(
10+
Dispatcher? dispatcher = null)
1011
{
1112
dispatcher ??= Application.Current?.Dispatcher ?? Dispatcher.CurrentDispatcher;
1213
this.dispatcher = dispatcher;
1314
}
1415

16+
public void Show(
17+
bool useDesktop,
18+
ToastNotificationMessage message,
19+
string areaName = "",
20+
TimeSpan? expirationTime = null,
21+
Action? onClick = null,
22+
Action? onClose = null)
23+
=> Show(
24+
useDesktop,
25+
message.ToToastNotificationContent(),
26+
areaName,
27+
expirationTime,
28+
onClick,
29+
onClose);
30+
31+
public void Show(
32+
bool useDesktop,
33+
ToastNotificationContent content,
34+
string areaName = "",
35+
TimeSpan? expirationTime = null,
36+
Action? onClick = null,
37+
Action? onClose = null)
38+
=> Show(
39+
useDesktop,
40+
(UserControl)content,
41+
areaName,
42+
expirationTime,
43+
onClick,
44+
onClose);
45+
1546
[SuppressMessage("Critical Code Smell", "S2696:Instance members should not write to \"static\" fields", Justification = "OK.")]
1647
public void Show(
1748
bool useDesktop,
18-
object content,
49+
UserControl content,
1950
string areaName = "",
2051
TimeSpan? expirationTime = null,
2152
Action? onClick = null,
@@ -25,7 +56,14 @@ public void Show(
2556

2657
if (!dispatcher.CheckAccess())
2758
{
28-
_ = dispatcher.BeginInvoke(new Action(() => Show(useDesktop, content, areaName, expirationTime, onClick, onClose)));
59+
_ = dispatcher.BeginInvoke(
60+
new Action(() => Show(
61+
useDesktop,
62+
content,
63+
areaName,
64+
expirationTime,
65+
onClick,
66+
onClose)));
2967
return;
3068
}
3169

@@ -47,19 +85,27 @@ public void Show(
4785
areaName = "DesktopArea";
4886
}
4987

50-
var toastNotificationAreas = Areas.Where(a => a.Name == areaName).ToArray();
88+
var toastNotificationAreas = Areas
89+
.Where(a => a.Name == areaName)
90+
.ToArray();
91+
5192
if (!toastNotificationAreas.Any())
5293
{
5394
toastNotificationAreas = Areas.Where(a => a.Name != "DesktopArea").ToArray();
5495
}
5596

5697
foreach (var area in toastNotificationAreas)
5798
{
58-
area.Show(content, (TimeSpan)expirationTime, onClick, onClose);
99+
area.Show(
100+
content,
101+
(TimeSpan)expirationTime,
102+
onClick,
103+
onClose);
59104
}
60105
}
61106

62-
internal static void AddArea(ToastNotificationArea area)
107+
internal static void AddArea(
108+
ToastNotificationArea area)
63109
{
64110
Areas.Add(area);
65111
}

src/Atc.Wpf.Controls/Notifications/ToastNotificationTemplateSelector.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ private void GetTemplatesFromResources(
1212
defaultToastNotificationTemplate = container?.FindResource("DefaultToastNotificationTemplate") as DataTemplate;
1313
}
1414

15-
public override DataTemplate? SelectTemplate(object item, DependencyObject container)
15+
public override DataTemplate? SelectTemplate(
16+
object? item,
17+
DependencyObject container)
1618
{
17-
if (defaultStringTemplate == null && defaultToastNotificationTemplate == null)
19+
if (defaultStringTemplate is null &&
20+
defaultToastNotificationTemplate is null)
1821
{
1922
GetTemplatesFromResources((FrameworkElement)container);
2023
}

0 commit comments

Comments
 (0)