diff --git a/samples/NotificationFlyoutSample/NotificationFlyoutSample/Shell.xaml b/samples/NotificationFlyoutSample/NotificationFlyoutSample/Shell.xaml
index a6e1b16..4f625e6 100644
--- a/samples/NotificationFlyoutSample/NotificationFlyoutSample/Shell.xaml
+++ b/samples/NotificationFlyoutSample/NotificationFlyoutSample/Shell.xaml
@@ -6,6 +6,9 @@
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
IconSource="/Assets/Icon.ico"
LightIconSource="/Assets/Icon-Light.ico">
+
+
+
addedItems, IList removedItems = null)
+ {
+ if (_flyout == null) return;
+
+ if (removedItems != null)
+ {
+ foreach (var item in removedItems)
+ {
+ _flyout.Items.Remove(item);
+ }
+ }
+
+ foreach (var item in addedItems)
+ {
+ _flyout.Items.Add(item);
+ }
}
}
}
\ No newline at end of file
diff --git a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/ContextMenuFlyoutHost.xaml b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/ContextMenuFlyoutHost.xaml
index 418315b..87cf47d 100644
--- a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/ContextMenuFlyoutHost.xaml
+++ b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/ContextMenuFlyoutHost.xaml
@@ -8,9 +8,7 @@
-
-
-
+
diff --git a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyout.cs b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyout.cs
index 17b6c27..3ef6557 100644
--- a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyout.cs
+++ b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyout.cs
@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
-using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
@@ -37,15 +38,17 @@ namespace NotificationFlyout.Uwp.UI.Controls
typeof(IList), typeof(NotificationFlyout),
new PropertyMetadata(null));
- internal event EventHandler ContentChanged;
- internal event EventHandler IconSourceChanged;
- internal event EventHandler RequestedThemeChanged;
-
public NotificationFlyout()
{
ContextMenuItems = new ObservableCollection();
+ (ContextMenuItems as INotifyCollectionChanged).CollectionChanged += OnContextMenuItemsChanged;
}
+ internal event EventHandler ContentChanged;
+ internal event EventHandler IconSourceChanged;
+ internal event EventHandler MenuItemsChanged;
+ internal event EventHandler RequestedThemeChanged;
+
public UIElement Content
{
get => (UIElement)GetValue(ContentProperty);
@@ -99,6 +102,14 @@ namespace NotificationFlyout.Uwp.UI.Controls
ContentChanged?.Invoke(this, EventArgs.Empty);
}
+ private void OnContextMenuItemsChanged(object sender, NotifyCollectionChangedEventArgs args)
+ {
+ var addedItems = args.NewItems.Cast().ToList();
+ var removedItems = args.NewItems.Cast().ToList();
+
+ MenuItemsChanged?.Invoke(this, new NotificationFlyoutMenuItemsChangedEventArgs(addedItems, removedItems));
+ }
+
private void OnIconPropertyChanged()
{
IconSourceChanged?.Invoke(this, EventArgs.Empty);
@@ -109,4 +120,17 @@ namespace NotificationFlyout.Uwp.UI.Controls
RequestedThemeChanged?.Invoke(this, EventArgs.Empty);
}
}
+
+ internal class NotificationFlyoutMenuItemsChangedEventArgs : EventArgs
+ {
+ public NotificationFlyoutMenuItemsChangedEventArgs(IList addedItems, IList removedItems)
+ {
+ AddedItems = addedItems;
+ RemovedItems = removedItems;
+ }
+
+ public IList AddedItems { get; private set; }
+
+ public IList RemovedItems { get; private set; }
+ }
}
diff --git a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs
index 6d533f2..57a1bab 100644
--- a/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs
+++ b/src/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.cs
@@ -42,6 +42,7 @@ namespace NotificationFlyout.Uwp.UI.Controls
_placement = placement;
}
+ if (string.IsNullOrEmpty(placement)) return;
VisualStateManager.GoToState(this, placement, true);
}
diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs
index 6e9b064..4e192df 100644
--- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs
+++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutApplication.cs
@@ -1,4 +1,5 @@
-using System.Windows;
+using System;
+using System.Windows;
using System.Windows.Markup;
namespace NotificationFlyout.Wpf.UI.Controls
@@ -11,12 +12,16 @@ namespace NotificationFlyout.Wpf.UI.Controls
typeof(Uwp.UI.Controls.NotificationFlyout), typeof(NotificationFlyoutApplication),
new PropertyMetadata(null, OnFlyoutPropertyChanged));
- private readonly NotificationFlyoutXamlHostWindow _xamlHost;
-
+ private readonly ContextMenuXamlHost _contextMenuXamlHost;
+ private readonly NotificationFlyoutXamlHost _notificationFlyoutXamlHost;
public NotificationFlyoutApplication()
{
- _xamlHost = new NotificationFlyoutXamlHostWindow();
- _xamlHost.Show();
+ _notificationFlyoutXamlHost = new NotificationFlyoutXamlHost();
+ _notificationFlyoutXamlHost.ContextMenuRequested += OnContextMenuRequested;
+ _notificationFlyoutXamlHost.Show();
+
+ _contextMenuXamlHost = new ContextMenuXamlHost();
+ _contextMenuXamlHost.Show();
}
public Uwp.UI.Controls.NotificationFlyout Flyout
@@ -27,12 +32,12 @@ namespace NotificationFlyout.Wpf.UI.Controls
public void HideFlyout()
{
- _xamlHost.HideFlyout();
+ _notificationFlyoutXamlHost.HideFlyout();
}
public void ShowFlyout()
{
- _xamlHost.ShowFlyout();
+ _notificationFlyoutXamlHost.ShowFlyout();
}
private static void OnFlyoutPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
@@ -41,9 +46,15 @@ namespace NotificationFlyout.Wpf.UI.Controls
sender?.OnFlyoutPropertyChanged();
}
+ private void OnContextMenuRequested(object sender, EventArgs args)
+ {
+ _contextMenuXamlHost?.ShowContextMenuFlyout();
+ }
+
private void OnFlyoutPropertyChanged()
{
- _xamlHost.SetFlyout(Flyout);
+ _notificationFlyoutXamlHost.SetFlyout(Flyout);
+ _contextMenuXamlHost.SetFlyout(Flyout);
}
}
}
\ No newline at end of file
diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs
index 67e836d..6c7b169 100644
--- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs
+++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutContextMenuXamlHost.cs
@@ -2,23 +2,29 @@
using NotificationFlyout.Wpf.UI.Extensions;
using NotificationFlyout.Wpf.UI.Helpers;
using System;
+using System.Collections.Generic;
+using Windows.UI.Xaml.Controls;
namespace NotificationFlyout.Wpf.UI.Controls
{
internal class ContextMenuXamlHost : XamlHostWindow
{
+ private Uwp.UI.Controls.NotificationFlyout _flyout;
+
public ContextMenuXamlHost()
{
Topmost = true;
}
- protected override void OnDeactivated(EventArgs args)
+ public void SetFlyout(Uwp.UI.Controls.NotificationFlyout flyout)
{
- var flyoutHost = GetHostContent();
- if (flyoutHost != null)
+ if (_flyout != null)
{
- flyoutHost.HideFlyout();
+ _flyout.MenuItemsChanged -= OnContextMenuItemsChanged;
}
+
+ _flyout = flyout;
+ UpdateMenuItems();
}
public void ShowContextMenuFlyout()
@@ -34,5 +40,39 @@ namespace NotificationFlyout.Wpf.UI.Controls
Activate();
}
+
+ protected override void OnContentLoaded()
+ {
+ UpdateMenuItems();
+ }
+
+ protected override void OnDeactivated(EventArgs args)
+ {
+ var flyoutHost = GetHostContent();
+ if (flyoutHost != null)
+ {
+ flyoutHost.HideFlyout();
+ }
+ }
+
+ private void OnContextMenuItemsChanged(object sender, NotificationFlyoutMenuItemsChangedEventArgs args)
+ {
+ UpdateMenuItems(args.AddedItems, args.RemovedItems);
+ }
+
+ private void UpdateMenuItems()
+ {
+ if (_flyout == null) return;
+ UpdateMenuItems(_flyout.ContextMenuItems);
+ }
+
+ private void UpdateMenuItems(IList addedItems, IList removedItems = default)
+ {
+ var flyoutHost = GetHostContent();
+ if (flyoutHost != null)
+ {
+ flyoutHost.SetMenuItems(addedItems, removedItems);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs
index 2ca5100..2e26307 100644
--- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs
+++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs
@@ -9,23 +9,17 @@ using System.Windows.Input;
namespace NotificationFlyout.Wpf.UI.Controls
{
- internal class NotificationFlyoutXamlHostWindow : XamlHostWindow
+ internal class NotificationFlyoutXamlHost : XamlHostWindow
{
private const string ShellTrayHandleName = "Shell_TrayWnd";
- private ContextMenuXamlHost _contextMenuXamlHost;
private Uwp.UI.Controls.NotificationFlyout _flyout;
- private bool _isLoaded;
-
private NotificationIconHelper _notificationIconHelper;
private SystemPersonalisationHelper _systemPersonalisationHelper;
private TaskbarHelper _taskbarHelper;
- public NotificationFlyoutXamlHostWindow()
- {
- Loaded += OnLoaded;
- }
+ internal event EventHandler ContextMenuRequested;
public void SetFlyout(Uwp.UI.Controls.NotificationFlyout flyout)
{
@@ -75,6 +69,13 @@ namespace NotificationFlyout.Wpf.UI.Controls
}
}
+ protected override void OnContentLoaded()
+ {
+ PrepareNotificationIcon();
+ PrepareTaskbar();
+ UpdateWindow();
+ }
+
protected override void OnDeactivated(EventArgs args)
{
HideFlyout();
@@ -104,20 +105,10 @@ namespace NotificationFlyout.Wpf.UI.Controls
if (args.MouseButton == MouseButton.Right)
{
- ShowContextMenuFlyout();
+ ContextMenuRequested?.Invoke(this, EventArgs.Empty);
}
}
- private void OnLoaded(object sender, RoutedEventArgs args)
- {
- PrepareNotificationIcon();
- PrepareTaskbar();
-
- _isLoaded = true;
-
- UpdateWindow();
- }
-
private void OnTaskbarChanged(object sender, EventArgs args)
{
UpdateWindow();
@@ -130,14 +121,13 @@ namespace NotificationFlyout.Wpf.UI.Controls
private void PrepareNotificationIcon()
{
- _contextMenuXamlHost = new ContextMenuXamlHost();
- _contextMenuXamlHost.Show();
-
_notificationIconHelper = NotificationIconHelper.Create(this);
_notificationIconHelper.IconInvoked += OnIconInvoked;
_systemPersonalisationHelper = SystemPersonalisationHelper.Create(this);
_systemPersonalisationHelper.ThemeChanged += OnThemeChanged;
+
+ UpdateIcons();
}
private void PrepareTaskbar()
@@ -145,10 +135,6 @@ namespace NotificationFlyout.Wpf.UI.Controls
_taskbarHelper = TaskbarHelper.Create(this);
_taskbarHelper.TaskbarChanged += OnTaskbarChanged;
}
- private void ShowContextMenuFlyout()
- {
- _contextMenuXamlHost.ShowContextMenuFlyout();
- }
private void UpdateFlyoutContent()
{
@@ -166,7 +152,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
private async void UpdateIcons()
{
- if (!_isLoaded) return;
+ if (!IsLoaded) return;
if (_flyout == null) return;
@@ -185,6 +171,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
_notificationIconHelper.SetIcon(icon.Handle);
}
+
private void UpdateRequestedTheme()
{
if (_flyout == null) return;
@@ -200,7 +187,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
private void UpdateWindow()
{
- if (!_isLoaded) return;
+ if (!IsLoaded) return;
var flyoutHost = GetHostContent();
if (flyoutHost == null) return;
diff --git a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/XamlHostWindow.cs b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/XamlHostWindow.cs
index 91b3e96..3e7a24d 100644
--- a/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/XamlHostWindow.cs
+++ b/src/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/XamlHostWindow.cs
@@ -1,33 +1,44 @@
using Microsoft.Toolkit.Wpf.UI.XamlHost;
using NotificationFlyout.Wpf.UI.Extensions;
+using System;
using System.Windows;
using System.Windows.Media;
namespace NotificationFlyout.Wpf.UI.Controls
{
- internal class XamlHostWindow : Window where TXamlContent : class
+ internal class XamlHostWindow : Window where TXamlContent : Windows.UI.Xaml.UIElement
{
internal const double WindowSize = 5;
+ protected new bool IsLoaded;
private WindowsXamlHost _xamlHost;
-
public XamlHostWindow()
{
PrepareDefaultWindow();
PrepareWindowsXamlHost();
Loaded += OnLoaded;
+ ContentRendered += OnContentRendered;
}
-
internal TXamlContent GetHostContent()
{
if (_xamlHost == null) return null;
return _xamlHost.GetUwpInternalObject() as TXamlContent;
}
+ protected virtual void OnContentLoaded()
+ {
+ }
+
+ private void OnContentRendered(object sender, EventArgs args)
+ {
+ IsLoaded = true;
+ OnContentLoaded();
+ }
+
private void OnLoaded(object sender, RoutedEventArgs args)
{
- this.Hidden();
+ this.Hidden();
}
private void PrepareDefaultWindow()
@@ -37,7 +48,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
WindowStyle = WindowStyle.None;
ResizeMode = ResizeMode.NoResize;
AllowsTransparency = true;
- Background = new SolidColorBrush(Colors.Red);
+ Background = new SolidColorBrush(Colors.Transparent);
Height = WindowSize;
Width = WindowSize;
}
@@ -46,14 +57,13 @@ namespace NotificationFlyout.Wpf.UI.Controls
{
_xamlHost = new WindowsXamlHost
{
- InitialTypeName = typeof(TXamlContent).FullName
+ InitialTypeName = typeof(TXamlContent).FullName,
+ Height = 0,
+ Width = 0,
+ HorizontalAlignment = HorizontalAlignment.Stretch,
+ VerticalAlignment = VerticalAlignment.Stretch
};
- _xamlHost.Height = 0;
- _xamlHost.Width = 0;
- _xamlHost.HorizontalAlignment = HorizontalAlignment.Stretch;
- _xamlHost.VerticalAlignment = VerticalAlignment.Stretch;
-
Content = _xamlHost;
}
}