Introduced a NotificationFlyoutPresenter to allow you to restyle/retemplate the flyout from within your UWP app

This commit is contained in:
Daniel Clark
2021-02-06 17:38:39 +00:00
parent 3de9ceee0d
commit 3fdfcfaf21
26 changed files with 260 additions and 282 deletions
@@ -1,26 +1,33 @@
using NotificationFlyout.Wpf.UI.Extensions;
using NotificationFlyout.Uwp.UI.Controls;
using NotificationFlyout.Wpf.UI.Extensions;
using NotificationFlyout.Wpf.UI.Helpers;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Media;
namespace NotificationFlyout.Wpf.UI.Controls
{
[ContentProperty(nameof(Content))]
[ContentProperty(nameof(FlyoutPresenter))]
public class NotificationFlyout : DependencyObject
{
public static readonly DependencyProperty IconSourceProperty =
DependencyProperty.Register(nameof(IconSource),
typeof(ImageSource), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static readonly DependencyProperty LightIconSourceProperty =
DependencyProperty.Register(nameof(LightIconSource),
typeof(ImageSource), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static DependencyProperty FlyoutPresenterProperty =
DependencyProperty.Register(nameof(FlyoutPresenter),
typeof(NotificationFlyoutPresenter), typeof(NotificationFlyout),
new PropertyMetadata(null, OnFlyoutPresenterPropertyChanged));
private const string ShellTrayHandleName = "Shell_TrayWnd";
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register(nameof(Icon),
typeof(NotificationFlyoutIcon), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content),
typeof(Windows.UI.Xaml.UIElement), typeof(NotificationFlyout),
new PropertyMetadata(null, OnContentPropertyChanged));
private NotificationFlyoutXamlHost _xamlHost;
private readonly NotificationFlyoutXamlHost _xamlHost;
public NotificationFlyout()
{
@@ -28,16 +35,22 @@ namespace NotificationFlyout.Wpf.UI.Controls
_xamlHost.Show();
}
public Windows.UI.Xaml.UIElement Content
public NotificationFlyoutPresenter FlyoutPresenter
{
get => (Windows.UI.Xaml.UIElement)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
get => (NotificationFlyoutPresenter)GetValue(FlyoutPresenterProperty);
set => SetValue(FlyoutPresenterProperty, value);
}
public NotificationFlyoutIcon Icon
public ImageSource IconSource
{
get => (NotificationFlyoutIcon)GetValue(IconProperty);
set => SetValue(IconProperty, value);
get => (ImageSource)GetValue(IconSourceProperty);
set => SetValue(IconSourceProperty, value);
}
public ImageSource LightIconSource
{
get => (ImageSource)GetValue(LightIconSourceProperty);
set => SetValue(LightIconSourceProperty, value);
}
public void HideFlyout()
@@ -50,10 +63,10 @@ namespace NotificationFlyout.Wpf.UI.Controls
_xamlHost.ShowFlyout();
}
private static void OnContentPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
private static void OnFlyoutPresenterPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var sender = dependencyObject as NotificationFlyout;
sender?.OnContentPropertyChanged();
sender?.OnFlyoutPresenterPropertyChanged();
}
private static void OnIconPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
@@ -62,9 +75,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
sender?.OnIconPropertyChanged();
}
private void OnContentPropertyChanged()
private void OnFlyoutPresenterPropertyChanged()
{
_xamlHost.SetFlyoutContent(Content);
_xamlHost.SetFlyoutPresenter(FlyoutPresenter);
}
private void OnIconPropertyChanged()
@@ -74,7 +87,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
var dpi = WindowHelper.GetDpi(shellTrayHandle);
var iconSource = SystemSettingsHelper.DefaultSystemTheme == SystemTheme.Dark ? Icon.IconSource : Icon.LightIconSource;
var iconSource = SystemSettingsHelper.DefaultSystemTheme == SystemTheme.Dark ? IconSource : LightIconSource;
using var icon = iconSource.ConvertToIcon(dpi);
_xamlHost.SetNotificationIcon(icon.Handle);
@@ -1,28 +0,0 @@
using System.Windows;
using System.Windows.Media;
namespace NotificationFlyout.Wpf.UI.Controls
{
public class NotificationFlyoutIcon : DependencyObject
{
public static readonly DependencyProperty IconSourceProperty =
DependencyProperty.Register(nameof(IconSource),
typeof(ImageSource), typeof(NotificationFlyout));
public static readonly DependencyProperty LightIconSourceProperty =
DependencyProperty.Register(nameof(LightIconSource),
typeof(ImageSource), typeof(NotificationFlyout));
public ImageSource IconSource
{
get => (ImageSource)GetValue(IconSourceProperty);
set => SetValue(IconSourceProperty, value);
}
public ImageSource LightIconSource
{
get => (ImageSource)GetValue(LightIconSourceProperty);
set => SetValue(LightIconSourceProperty, value);
}
}
}
@@ -12,10 +12,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
internal class NotificationFlyoutXamlHost : Window
{
private const double MaximumOffset = 80;
private WindowsXamlHost _host;
private NotificationIconHelper _notificationIconHelper;
private TaskbarHelper _taskbarHelper;
private WindowsXamlHost _xamlHost;
public NotificationFlyoutXamlHost()
{
@@ -25,21 +24,21 @@ namespace NotificationFlyout.Wpf.UI.Controls
Loaded += OnLoaded;
}
public void SetFlyoutContent(Windows.UI.Xaml.UIElement content)
public void SetFlyoutPresenter(NotificationFlyoutPresenter flyoutPresenter)
{
var flyoutPresenter = GetNotificationFlyoutPresenter();
if (flyoutPresenter != null)
var flyoutHost = GetFlyoutHost();
if (flyoutHost != null)
{
flyoutPresenter.Content = content;
flyoutHost.FlyoutPresenter = flyoutPresenter;
}
}
internal void HideFlyout()
{
var flyoutContentControl = GetNotificationFlyoutPresenter();
if (flyoutContentControl != null)
var flyoutHost = GetFlyoutHost();
if (flyoutHost != null)
{
flyoutContentControl.HideFlyout();
flyoutHost.HideFlyout();
}
}
@@ -47,10 +46,11 @@ namespace NotificationFlyout.Wpf.UI.Controls
{
_notificationIconHelper.SetIcon(handle);
}
internal void ShowFlyout()
{
var flyoutPresenter = GetNotificationFlyoutPresenter();
if (flyoutPresenter != null)
var flyoutHost = GetFlyoutHost();
if (flyoutHost != null)
{
var taskbarState = _taskbarHelper.GetCurrentState();
var flyoutPlacement = taskbarState.Position switch
@@ -63,15 +63,16 @@ namespace NotificationFlyout.Wpf.UI.Controls
};
Activate();
flyoutPresenter.ShowFlyout(flyoutPlacement);
flyoutHost.ShowFlyout(flyoutPlacement);
}
}
private NotificationFlyoutPresenter GetNotificationFlyoutPresenter()
private NotificationFlyoutHost GetFlyoutHost()
{
if (_host == null) return null;
return _host.GetUwpInternalObject() as NotificationFlyoutPresenter;
if (_xamlHost == null) return null;
return _xamlHost.GetUwpInternalObject() as NotificationFlyoutHost;
}
private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args)
{
ShowFlyout();
@@ -120,21 +121,21 @@ namespace NotificationFlyout.Wpf.UI.Controls
private void PrepareWindowsXamlHost()
{
_host = new WindowsXamlHost
_xamlHost = new WindowsXamlHost
{
InitialTypeName = typeof(NotificationFlyoutPresenter).FullName
InitialTypeName = typeof(NotificationFlyoutHost).FullName
};
_host.Height = 0;
_host.Width = 0;
_xamlHost.Height = 0;
_xamlHost.Width = 0;
Content = _host;
Content = _xamlHost;
}
private void UpdateWindow()
{
var flyoutPresenter = GetNotificationFlyoutPresenter();
if (flyoutPresenter == null) return;
var flyoutHost = GetFlyoutHost();
if (flyoutHost == null) return;
var taskbarState = _taskbarHelper.GetCurrentState();
@@ -187,7 +188,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
}
this.SetWindowPosition(top, left, height, width);
flyoutPresenter.SetOffset(verticalOffset, horizontalOffset);
flyoutHost.SetOffset(verticalOffset, horizontalOffset);
}
}
}