diff --git a/NotificationFlyout.Foundation/NotificationFlyout.Foundation.csproj b/NotificationFlyout.Foundation/NotificationFlyout.Foundation.csproj
new file mode 100644
index 0000000..5ac91c0
--- /dev/null
+++ b/NotificationFlyout.Foundation/NotificationFlyout.Foundation.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netcoreapp3.1
+ AnyCPU;x64
+
+
+
diff --git a/NotificationFlyout.Package/Images/LockScreenLogo.scale-200.png b/NotificationFlyout.Package/Images/LockScreenLogo.scale-200.png
new file mode 100644
index 0000000..735f57a
Binary files /dev/null and b/NotificationFlyout.Package/Images/LockScreenLogo.scale-200.png differ
diff --git a/NotificationFlyout.Package/Images/SplashScreen.scale-200.png b/NotificationFlyout.Package/Images/SplashScreen.scale-200.png
new file mode 100644
index 0000000..023e7f1
Binary files /dev/null and b/NotificationFlyout.Package/Images/SplashScreen.scale-200.png differ
diff --git a/NotificationFlyout.Package/Images/Square150x150Logo.scale-200.png b/NotificationFlyout.Package/Images/Square150x150Logo.scale-200.png
new file mode 100644
index 0000000..af49fec
Binary files /dev/null and b/NotificationFlyout.Package/Images/Square150x150Logo.scale-200.png differ
diff --git a/NotificationFlyout.Package/Images/Square44x44Logo.scale-200.png b/NotificationFlyout.Package/Images/Square44x44Logo.scale-200.png
new file mode 100644
index 0000000..ce342a2
Binary files /dev/null and b/NotificationFlyout.Package/Images/Square44x44Logo.scale-200.png differ
diff --git a/NotificationFlyout.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/NotificationFlyout.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png
new file mode 100644
index 0000000..f6c02ce
Binary files /dev/null and b/NotificationFlyout.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png differ
diff --git a/NotificationFlyout.Package/Images/StoreLogo.png b/NotificationFlyout.Package/Images/StoreLogo.png
new file mode 100644
index 0000000..7385b56
Binary files /dev/null and b/NotificationFlyout.Package/Images/StoreLogo.png differ
diff --git a/NotificationFlyout.Package/Images/Wide310x150Logo.scale-200.png b/NotificationFlyout.Package/Images/Wide310x150Logo.scale-200.png
new file mode 100644
index 0000000..288995b
Binary files /dev/null and b/NotificationFlyout.Package/Images/Wide310x150Logo.scale-200.png differ
diff --git a/NotificationFlyout.Package/NotificationFlyout.Package.wapproj b/NotificationFlyout.Package/NotificationFlyout.Package.wapproj
new file mode 100644
index 0000000..a93c168
--- /dev/null
+++ b/NotificationFlyout.Package/NotificationFlyout.Package.wapproj
@@ -0,0 +1,118 @@
+
+
+
+ 15.0
+
+
+
+ Debug
+ x86
+
+
+ Release
+ x86
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+ Debug
+ ARM
+
+
+ Release
+ ARM
+
+
+ Debug
+ ARM64
+
+
+ Release
+ ARM64
+
+
+ Debug
+ AnyCPU
+
+
+ Release
+ AnyCPU
+
+
+
+ $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\
+
+
+
+ 46ff88d3-c2c7-419b-94f6-1ac01307c31a
+ 10.0.19041.0
+ 10.0.19041.0
+ en-US
+ false
+ ..\NotificationFlyout.Tray\NotificationFlyout.Tray.csproj
+ False
+ True
+ True
+ neutral
+ 0
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Package/Package.appxmanifest b/NotificationFlyout.Package/Package.appxmanifest
new file mode 100644
index 0000000..9ebfeff
--- /dev/null
+++ b/NotificationFlyout.Package/Package.appxmanifest
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ NotificationFlyout.Package
+ dan
+ Images\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotificationFlyout.Sample/MyUserControl1.xaml b/NotificationFlyout.Sample/MyUserControl1.xaml
new file mode 100644
index 0000000..c5a3e26
--- /dev/null
+++ b/NotificationFlyout.Sample/MyUserControl1.xaml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotificationFlyout.Sample/MyUserControl1.xaml.cs b/NotificationFlyout.Sample/MyUserControl1.xaml.cs
new file mode 100644
index 0000000..3ee4049
--- /dev/null
+++ b/NotificationFlyout.Sample/MyUserControl1.xaml.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using Windows.Foundation;
+using Windows.Foundation.Collections;
+using Windows.UI.Xaml;
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+using Windows.UI.Xaml.Data;
+using Windows.UI.Xaml.Input;
+using Windows.UI.Xaml.Media;
+using Windows.UI.Xaml.Navigation;
+
+// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
+
+namespace NotificationFlyout.Sample
+{
+ public sealed partial class MyUserControl1 : UserControl
+ {
+ public MyUserControl1()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
diff --git a/NotificationFlyout.Sample/NotificationFlyout.Sample.csproj b/NotificationFlyout.Sample/NotificationFlyout.Sample.csproj
new file mode 100644
index 0000000..1c63192
--- /dev/null
+++ b/NotificationFlyout.Sample/NotificationFlyout.Sample.csproj
@@ -0,0 +1,151 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {675B9345-F416-44EF-8154-B7F6943877FA}
+ Library
+ Properties
+ NotificationFlyout.Sample
+ NotificationFlyout.Sample
+ en-US
+ UAP
+ 10.0.19041.0
+ 10.0.19041.0
+ 14
+ 512
+ {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ x86
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ x86
+ bin\x86\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ ARM
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ ARM
+ bin\ARM\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ ARM64
+ true
+ bin\ARM64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ ARM64
+ bin\ARM64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ x64
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ x64
+ bin\x64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ PackageReference
+
+
+
+ MyUserControl1.xaml
+
+
+
+
+
+
+ 6.2.11
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+ 14.0
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Sample/Properties/AssemblyInfo.cs b/NotificationFlyout.Sample/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..52caaf9
--- /dev/null
+++ b/NotificationFlyout.Sample/Properties/AssemblyInfo.cs
@@ -0,0 +1,29 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NotificationFlyout.Sample")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NotificationFlyout.Sample")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/NotificationFlyout.Sample/Properties/NotificationFlyout.Sample.rd.xml b/NotificationFlyout.Sample/Properties/NotificationFlyout.Sample.rd.xml
new file mode 100644
index 0000000..5e30990
--- /dev/null
+++ b/NotificationFlyout.Sample/Properties/NotificationFlyout.Sample.rd.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
diff --git a/NotificationFlyout.Tray/App.xaml b/NotificationFlyout.Tray/App.xaml
new file mode 100644
index 0000000..46b9bb7
--- /dev/null
+++ b/NotificationFlyout.Tray/App.xaml
@@ -0,0 +1,4 @@
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Tray/App.xaml.cs b/NotificationFlyout.Tray/App.xaml.cs
new file mode 100644
index 0000000..2f338d1
--- /dev/null
+++ b/NotificationFlyout.Tray/App.xaml.cs
@@ -0,0 +1,8 @@
+using System.Windows;
+
+namespace NotificationFlyout.Tray
+{
+ public partial class App : Application
+ {
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Tray/Assets/Icon.ico b/NotificationFlyout.Tray/Assets/Icon.ico
new file mode 100644
index 0000000..6375e26
Binary files /dev/null and b/NotificationFlyout.Tray/Assets/Icon.ico differ
diff --git a/NotificationFlyout.Tray/NotificationFlyout.Tray.csproj b/NotificationFlyout.Tray/NotificationFlyout.Tray.csproj
new file mode 100644
index 0000000..2e6895c
--- /dev/null
+++ b/NotificationFlyout.Tray/NotificationFlyout.Tray.csproj
@@ -0,0 +1,31 @@
+
+
+
+ WinExe
+ netcoreapp3.1
+ true
+ uap10.0.19041
+ AnyCPU;x64
+ NotificationFlyout.Tray.Program
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotificationFlyout.Tray/Program.cs b/NotificationFlyout.Tray/Program.cs
new file mode 100644
index 0000000..3f2f8b7
--- /dev/null
+++ b/NotificationFlyout.Tray/Program.cs
@@ -0,0 +1,19 @@
+using NotificationFlyout.Tray.Views;
+using System;
+
+namespace NotificationFlyout.Tray
+{
+ public class Program
+ {
+ [STAThread()]
+ public static void Main()
+ {
+ using (new XamlHost.App())
+ {
+ var app = new App();
+ new Shell();
+ app.Run();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Tray/Properties/AssemblyInfo.cs b/NotificationFlyout.Tray/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4f943de
--- /dev/null
+++ b/NotificationFlyout.Tray/Properties/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
\ No newline at end of file
diff --git a/NotificationFlyout.Tray/Views/Shell.xaml b/NotificationFlyout.Tray/Views/Shell.xaml
new file mode 100644
index 0000000..8d177be
--- /dev/null
+++ b/NotificationFlyout.Tray/Views/Shell.xaml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/NotificationFlyout.Tray/Views/Shell.xaml.cs b/NotificationFlyout.Tray/Views/Shell.xaml.cs
new file mode 100644
index 0000000..46cb886
--- /dev/null
+++ b/NotificationFlyout.Tray/Views/Shell.xaml.cs
@@ -0,0 +1,10 @@
+namespace NotificationFlyout.Tray.Views
+{
+ public partial class Shell
+ {
+ public Shell()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj
new file mode 100644
index 0000000..a37733c
--- /dev/null
+++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyout.Uwp.UI.Controls.csproj
@@ -0,0 +1,157 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {9987B132-E42C-401A-9AD5-E62529FACA40}
+ Library
+ Properties
+ NotificationFlyout.Uwp.UI.Controls
+ NotificationFlyout.Uwp.UI.Controls
+ en-US
+ UAP
+ 10.0.19041.0
+ 10.0.19041.0
+ 14
+ 512
+ {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ x86
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ x86
+ bin\x86\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ ARM
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ ARM
+ bin\ARM\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ ARM64
+ true
+ bin\ARM64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ ARM64
+ bin\ARM64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ x64
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ x64
+ bin\x64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ PackageReference
+
+
+
+
+
+
+
+
+ 6.2.11
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+ 14.0
+
+
+
+
+ false
+ false
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs
new file mode 100644
index 0000000..9ec130a
--- /dev/null
+++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.cs
@@ -0,0 +1,41 @@
+using Windows.UI.Xaml.Controls;
+using Windows.UI.Xaml.Controls.Primitives;
+
+namespace NotificationFlyout.Uwp.UI.Controls
+{
+ public class NotificationFlyoutPresenter : ContentControl
+ {
+ private Grid _root;
+
+ public NotificationFlyoutPresenter()
+ {
+ DefaultStyleKey = typeof(NotificationFlyoutPresenter);
+ }
+
+ public void HideFlyout()
+ {
+ if (_root == null) return;
+ var flyout = FlyoutBase.GetAttachedFlyout(_root);
+ flyout.Hide();
+ }
+
+ public void ShowFlyout(FlyoutPlacementMode placementMode)
+ {
+ if (_root == null) return;
+ var flyout = FlyoutBase.GetAttachedFlyout(_root);
+ flyout.ShowAt(_root, new FlyoutShowOptions { Placement = placementMode });
+ }
+
+ public void ShowFlyout()
+ {
+ if (_root == null) return;
+ var flyout = FlyoutBase.GetAttachedFlyout(_root);
+ flyout.ShowAt(_root);
+ }
+
+ protected override void OnApplyTemplate()
+ {
+ _root = GetTemplateChild("Root") as Grid;
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml
new file mode 100644
index 0000000..4557e72
--- /dev/null
+++ b/NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml
@@ -0,0 +1,20 @@
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Uwp.UI.Controls/Properties/AssemblyInfo.cs b/NotificationFlyout.Uwp.UI.Controls/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..f214d3a
--- /dev/null
+++ b/NotificationFlyout.Uwp.UI.Controls/Properties/AssemblyInfo.cs
@@ -0,0 +1,28 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NotificationFlyout.Uwp.UI.Controls")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NotificationFlyout.Uwp.UI.Controls")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/NotificationFlyout.Uwp.UI.Controls/Properties/NotificationFlyout.Uwp.UI.Controls.rd.xml b/NotificationFlyout.Uwp.UI.Controls/Properties/NotificationFlyout.Uwp.UI.Controls.rd.xml
new file mode 100644
index 0000000..0d8e415
--- /dev/null
+++ b/NotificationFlyout.Uwp.UI.Controls/Properties/NotificationFlyout.Uwp.UI.Controls.rd.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Uwp.UI.Controls/Themes/Generic.xaml b/NotificationFlyout.Uwp.UI.Controls/Themes/Generic.xaml
new file mode 100644
index 0000000..bbc6012
--- /dev/null
+++ b/NotificationFlyout.Uwp.UI.Controls/Themes/Generic.xaml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj
new file mode 100644
index 0000000..8731fa3
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout.Wpf.UI.Controls.csproj
@@ -0,0 +1,19 @@
+
+
+
+ netcoreapp3.1
+ true
+ uap10.0.19041
+ AnyCPU;x64
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyout.cs b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyout.cs
new file mode 100644
index 0000000..a8400b8
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyout.cs
@@ -0,0 +1,81 @@
+using NotificationFlyout.Wpf.UI.Extensions;
+using NotificationFlyout.Wpf.UI.Helpers;
+using System.Windows;
+
+namespace NotificationFlyout.Wpf.UI.Controls
+{
+ public class NotificationFlyout : DependencyObject
+ {
+ 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 FlyoutContentProperty =
+ DependencyProperty.Register(nameof(FlyoutContent),
+ typeof(Windows.UI.Xaml.UIElement), typeof(NotificationFlyout),
+ new PropertyMetadata(null, OnFlyoutContentPropertyChanged));
+
+ private NotificationFlyoutXamlHost _xamlHost;
+
+ public NotificationFlyout()
+ {
+ _xamlHost = new NotificationFlyoutXamlHost();
+ _xamlHost.Show();
+ }
+
+ public Windows.UI.Xaml.UIElement FlyoutContent
+ {
+ get => (Windows.UI.Xaml.UIElement)GetValue(FlyoutContentProperty);
+ set => SetValue(FlyoutContentProperty, value);
+ }
+
+ public NotificationFlyoutIcon Icon
+ {
+ get => (NotificationFlyoutIcon)GetValue(IconProperty);
+ set => SetValue(IconProperty, value);
+ }
+
+ public void HideFlyout()
+ {
+ _xamlHost.HideFlyout();
+ }
+
+ public void ShowFlyout()
+ {
+ _xamlHost.ShowFlyout();
+ }
+
+ private static void OnFlyoutContentPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
+ {
+ var sender = dependencyObject as NotificationFlyout;
+ sender?.OnFlyoutContentPropertyChanged();
+ }
+
+ private static void OnIconPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
+ {
+ var sender = dependencyObject as NotificationFlyout;
+ sender?.OnIconPropertyChanged();
+ }
+
+ private void OnFlyoutContentPropertyChanged()
+ {
+ _xamlHost.FlyoutContent = FlyoutContent;
+ }
+
+ private void OnIconPropertyChanged()
+ {
+ var shellTrayHandle = WindowHelper.GetHandle(ShellTrayHandleName);
+ if (shellTrayHandle == null) return;
+
+ var dpi = WindowHelper.GetDpi(shellTrayHandle);
+
+ var iconSource = SystemSettingsHelper.DefaultSystemTheme == SystemTheme.Dark ? Icon.IconSource : Icon.LightIconSource;
+ using var icon = iconSource.ConvertToIcon(dpi);
+
+ _xamlHost.SetNotificationIcon(icon.Handle);
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutIcon.cs b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutIcon.cs
new file mode 100644
index 0000000..323b78a
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutIcon.cs
@@ -0,0 +1,28 @@
+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);
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs
new file mode 100644
index 0000000..5566654
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI.Controls/NotificationFlyout/NotificationFlyoutXamlHost.cs
@@ -0,0 +1,193 @@
+using Microsoft.Toolkit.Wpf.UI.XamlHost;
+using NotificationFlyout.Uwp.UI.Controls;
+using NotificationFlyout.Wpf.UI.Extensions;
+using NotificationFlyout.Wpf.UI.Helpers;
+using System;
+using System.Windows;
+using Windows.UI.Xaml.Controls.Primitives;
+
+namespace NotificationFlyout.Wpf.UI.Controls
+{
+ internal class NotificationFlyoutXamlHost : Window
+ {
+ internal static DependencyProperty FlyoutContentProperty =
+ DependencyProperty.Register(nameof(FlyoutContent),
+ typeof(Windows.UI.Xaml.UIElement), typeof(NotificationFlyoutXamlHost),
+ new PropertyMetadata(null, OnFlyoutContentPropertyChanged));
+
+ private WindowsXamlHost _host;
+
+ private NotificationIconHelper _notificationIconHelper;
+ private bool _taskbarChanged;
+ private TaskbarHelper _taskbarHelper;
+
+ public NotificationFlyoutXamlHost()
+ {
+ PrepareDefaultWindow();
+ PrepareWindowsXamlHost();
+
+ Loaded += OnLoaded;
+ }
+
+ public Windows.UI.Xaml.UIElement FlyoutContent
+ {
+ get => (Windows.UI.Xaml.UIElement)GetValue(FlyoutContentProperty);
+ set => SetValue(FlyoutContentProperty, value);
+ }
+
+ internal void HideFlyout()
+ {
+ var flyoutContentControl = GetNotificationFlyoutPresenter();
+ if (flyoutContentControl != null)
+ {
+ flyoutContentControl.HideFlyout();
+ }
+ }
+
+ internal void SetNotificationIcon(IntPtr handle)
+ {
+ _notificationIconHelper.SetIcon(handle);
+ }
+
+ internal void ShowFlyout()
+ {
+ var flyoutContentControl = GetNotificationFlyoutPresenter();
+ if (flyoutContentControl != null)
+ {
+ var taskbarState = _taskbarHelper.GetCurrentState();
+
+ var flyoutPlacement = FlyoutPlacementMode.Bottom;
+ switch (taskbarState.Position)
+ {
+ case TaskbarPosition.Left:
+ flyoutPlacement = FlyoutPlacementMode.Right;
+ break;
+ case TaskbarPosition.Top:
+ flyoutPlacement = FlyoutPlacementMode.Bottom;
+ break;
+ case TaskbarPosition.Right:
+ flyoutPlacement = FlyoutPlacementMode.Left;
+ break;
+ case TaskbarPosition.Bottom:
+ flyoutPlacement = FlyoutPlacementMode.Top;
+ break;
+ }
+
+ UpdateWindow();
+ Activate();
+
+ flyoutContentControl.ShowFlyout(flyoutPlacement);
+ }
+ }
+
+ private static void OnFlyoutContentPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
+ {
+ var sender = dependencyObject as NotificationFlyoutXamlHost;
+ sender?.OnFlyoutContentPropertyChanged();
+ }
+
+ private NotificationFlyoutPresenter GetNotificationFlyoutPresenter()
+ {
+ return _host.GetUwpInternalObject() as NotificationFlyoutPresenter;
+ }
+
+ private void OnFlyoutContentPropertyChanged()
+ {
+ var flyoutContentControl = GetNotificationFlyoutPresenter();
+ if (flyoutContentControl != null)
+ {
+ flyoutContentControl.Content = FlyoutContent;
+ }
+ }
+
+ private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args)
+ {
+ ShowFlyout();
+ }
+
+ private void OnLoaded(object sender, RoutedEventArgs args)
+ {
+ PrepareNotificationIcon();
+ PrepareTaskbar();
+
+ UpdateWindow();
+ }
+
+ private void OnTaskbarChanged(object sender, EventArgs args)
+ {
+ _taskbarChanged = true;
+
+ var taskbarState = _taskbarHelper.GetCurrentState();
+ Left = taskbarState.Screen.WorkingArea.Left;
+ Top = taskbarState.Screen.WorkingArea.Top;
+
+ UpdateWindow();
+ }
+
+ private void PrepareDefaultWindow()
+ {
+ ShowInTaskbar = false;
+ ShowActivated = false;
+ WindowStyle = WindowStyle.None;
+ ResizeMode = ResizeMode.NoResize;
+ AllowsTransparency = true;
+ Height = 0;
+ Width = 0;
+ }
+
+ private void PrepareNotificationIcon()
+ {
+ _notificationIconHelper = NotificationIconHelper.Create(this);
+ _notificationIconHelper.IconInvoked += OnIconInvoked;
+ }
+
+ private void PrepareTaskbar()
+ {
+ _taskbarHelper = TaskbarHelper.Create(this);
+ _taskbarHelper.TaskbarChanged += OnTaskbarChanged;
+ }
+
+ private void PrepareWindowsXamlHost()
+ {
+ _host = new WindowsXamlHost
+ {
+ InitialTypeName = typeof(NotificationFlyoutPresenter).FullName
+ };
+
+ _host.Height = 0;
+ _host.Width = 0;
+
+ Content = _host;
+ }
+
+ private void UpdateWindow()
+ {
+ var taskbarState = _taskbarHelper.GetCurrentState();
+
+ var screen = Screen.FromHandle(this.GetHandle());
+ MaxHeight = screen.Bounds.Height / 2;
+
+ var windowWidth = DesiredSize.Width * this.DpiX();
+ var windowHeight = DesiredSize.Height * this.DpiY();
+
+ var taskbarRect = taskbarState.Rect;
+ switch (taskbarState.Position)
+ {
+ case TaskbarPosition.Left:
+ this.SetWindowPosition(taskbarRect.Bottom - windowHeight, taskbarRect.Right, windowHeight, windowWidth);
+ break;
+ case TaskbarPosition.Top:
+ this.SetWindowPosition(taskbarRect.Bottom, FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth, windowHeight, windowWidth);
+ break;
+ case TaskbarPosition.Right:
+ this.SetWindowPosition(taskbarRect.Bottom - windowHeight, taskbarRect.Left - windowWidth, windowHeight, windowWidth);
+ break;
+ case TaskbarPosition.Bottom:
+ this.SetWindowPosition(taskbarRect.Top - windowHeight, FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth, windowHeight, windowWidth);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI.Controls/Properties/AssemblyInfo.cs b/NotificationFlyout.Wpf.UI.Controls/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d121981
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI.Controls/Properties/AssemblyInfo.cs
@@ -0,0 +1,5 @@
+using System.Windows;
+using System.Windows.Markup;
+
+[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "NotificationFlyout.Wpf.UI.Controls")]
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs b/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs
new file mode 100644
index 0000000..0f8e591
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/ImageSourceExtensions.cs
@@ -0,0 +1,31 @@
+using Microsoft.Windows.Sdk;
+using System;
+using System.Drawing;
+using System.Windows;
+using System.Windows.Media;
+
+namespace NotificationFlyout.Wpf.UI.Extensions
+{
+ public static class ImageSourceExtensions
+ {
+ public static Icon ConvertToIcon(this ImageSource imageSource, uint dpi)
+ {
+ if (imageSource == null) return null;
+
+ var uri = new Uri(imageSource.ToString(), UriKind.RelativeOrAbsolute);
+
+ var streamResource = Application.GetResourceStream(uri);
+ if (streamResource == null) throw new ArgumentException(nameof(streamResource));
+
+ return new Icon(streamResource.Stream, new System.Drawing.Size(PInvoke.GetSystemMetricsForDpi((int)SystemMetricFlag.SM_CXICON, dpi), PInvoke.GetSystemMetricsForDpi((int)SystemMetricFlag.SM_CYICON, dpi)));
+ }
+
+ private enum SystemMetricFlag : int
+ {
+ SM_CXICON = 11,
+ SM_CYICON = 12,
+ SM_CXSMICON = 49,
+ SM_CYSMICON = 50
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs b/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs
new file mode 100644
index 0000000..50d2dae
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemExtensions.cs
@@ -0,0 +1,13 @@
+using NotificationFlyout.Wpf.UI.Helpers;
+using System;
+
+namespace NotificationFlyout.Wpf.UI.Extensions
+{
+ public static class OperatingSystemExtensions
+ {
+ public static bool IsGreaterThan(this OperatingSystem operatingSystem, OperatingSystemVersion version)
+ {
+ return operatingSystem.Version.Build > (int)version;
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemVersion.cs b/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemVersion.cs
new file mode 100644
index 0000000..43b24e5
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/OperatingSystemVersion.cs
@@ -0,0 +1,14 @@
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public enum OperatingSystemVersion : int
+ {
+ Windows10 = 10240,
+ Windows10_1511 = 10586,
+ Windows10_1607 = 14393,
+ Windows10_1703 = 15063,
+ Windows10_1709 = 16299,
+ Windows10_1803 = 17134,
+ Windows10_1809 = 17763,
+ Windows10_1903 = 18362
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Extensions/RECTExtensions.cs b/NotificationFlyout.Wpf.UI/Extensions/RECTExtensions.cs
new file mode 100644
index 0000000..8ad0dc7
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/RECTExtensions.cs
@@ -0,0 +1,15 @@
+using Microsoft.Windows.Sdk;
+using System.Windows;
+
+namespace NotificationFlyout.Wpf.UI.Extensions
+{
+ internal static class RECTExtensions
+ {
+ internal static Rect ToRect(this RECT rect)
+ {
+ if (rect.right - rect.left < 0 || rect.bottom - rect.top < 0) return new Rect(rect.left, rect.top, 0, 0);
+
+ return new Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Extensions/RegistryKeyExtensions.cs b/NotificationFlyout.Wpf.UI/Extensions/RegistryKeyExtensions.cs
new file mode 100644
index 0000000..7060f66
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/RegistryKeyExtensions.cs
@@ -0,0 +1,12 @@
+using Microsoft.Win32;
+
+namespace NotificationFlyout.Wpf.UI.Extensions
+{
+ public static class RegistryKeyExtensions
+ {
+ public static T GetValue(this RegistryKey self, string valueName, T defaultValue)
+ {
+ return self.GetValue(valueName, defaultValue) is T t ? t : defaultValue;
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Extensions/VisualExtensions.cs b/NotificationFlyout.Wpf.UI/Extensions/VisualExtensions.cs
new file mode 100644
index 0000000..58b3dc5
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/VisualExtensions.cs
@@ -0,0 +1,39 @@
+using System.Windows;
+using System.Windows.Media;
+
+namespace NotificationFlyout.Wpf.UI.Extensions
+{
+ public static class VisualExtensions
+ {
+ private static Matrix GetDpi(this Visual visual)
+ {
+ var source = PresentationSource.FromVisual(visual);
+ if (source?.CompositionTarget != null) return (Matrix)source?.CompositionTarget.TransformToDevice;
+
+ return default;
+ }
+
+ public static double DpiY(this Visual visual)
+ {
+ return GetDpi(visual).M22;
+ }
+
+ public static double DpiX(this Visual visual)
+ {
+ return GetDpi(visual).M11;
+ }
+
+ public static bool TryGetTransformToDevice(this Visual visual, out Matrix value)
+ {
+ var presentationSource = PresentationSource.FromVisual(visual);
+ if (presentationSource != null)
+ {
+ value = presentationSource.CompositionTarget.TransformToDevice;
+ return true;
+ }
+
+ value = default;
+ return false;
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Extensions/WindowExtensions.cs b/NotificationFlyout.Wpf.UI/Extensions/WindowExtensions.cs
new file mode 100644
index 0000000..3f22693
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Extensions/WindowExtensions.cs
@@ -0,0 +1,37 @@
+using Microsoft.Windows.Sdk;
+using System;
+using System.Windows;
+using System.Windows.Interop;
+
+namespace NotificationFlyout.Wpf.UI.Extensions
+{
+ public static class WindowExtensions
+ {
+ [Flags]
+ private enum WindowFlag : uint
+ {
+ SWP_NOSIZE = 0x0001,
+ SWP_NOMOVE = 0x0002,
+ SWP_NOZORDER = 0x0004,
+ SWP_NOACTIVATE = 0x0010,
+ WS_EX_NOACTIVATE = 0x08000000,
+ SWP_SHOWWINDOW = 0x0040
+ }
+
+ public static void SetWindowPosition(this Window window, double top, double left, double height, double width)
+ {
+ PInvoke.SetWindowPos((HWND)window.GetHandle(), (HWND)IntPtr.Zero, (int)left, (int)top, (int)width, (int)height, (uint)WindowFlag.SWP_NOSIZE | (uint)WindowFlag.SWP_NOZORDER | (uint)WindowFlag.SWP_NOACTIVATE);
+ }
+
+ public static void SetTopAll(this Window window)
+ {
+ PInvoke.SetWindowPos((HWND)window.GetHandle(), (HWND)new IntPtr(-1), 0, 0, 0, 0, (uint)WindowFlag.SWP_NOMOVE | (uint)WindowFlag.SWP_NOSIZE | (uint)WindowFlag.WS_EX_NOACTIVATE);
+ }
+
+ public static IntPtr GetHandle(this Window window)
+ {
+ var helper = new WindowInteropHelper(window);
+ return helper.Handle;
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs b/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs
new file mode 100644
index 0000000..73b02ea
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/NotificationIconHelper.cs
@@ -0,0 +1,209 @@
+using Microsoft.Windows.Sdk;
+using NotificationFlyout.Wpf.UI.Extensions;
+using System;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Interop;
+
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public class NotificationIconHelper : IDisposable
+ {
+ private const int CallbackMessage = 0x400;
+ private const uint IconVersion = 0x4;
+
+ private const int WM_LBUTTONUP = 0x0202;
+ private const int WM_MBUTTONUP = 0x0208;
+ private const int WM_RBUTTONUP = 0x0205;
+ private readonly object _lock = new();
+ private readonly IntPtr _windowHandle;
+ private bool _isDisposed;
+ private NotifyIconData _notifyIconData;
+
+ private NotificationIconHelper(Window window)
+ {
+ _windowHandle = window.GetHandle();
+
+ var source = HwndSource.FromHwnd(_windowHandle);
+ source.AddHook(new HwndSourceHook(WndProc));
+
+ CreateNotificationIcon();
+ }
+
+
+ ~NotificationIconHelper()
+ {
+ Dispose(false);
+ }
+
+ public event EventHandler IconInvoked;
+
+ private enum NotifyIconBalloonType
+ {
+ None = 0x00,
+ Info = 0x01,
+ Warning = 0x02,
+ Error = 0x03,
+ User = 0x04,
+ NoSound = 0x10,
+ LargeIcon = 0x20,
+ RespectQuietTime = 0x80
+ }
+
+ private enum NotifyIconCommand : uint
+ {
+ Add = 0x0,
+ Delete = 0x2,
+ Modify = 0x1,
+ SetVersion = 0x4
+ }
+
+ [Flags]
+ private enum NotifyIconDataMember : uint
+ {
+ Message = 0x01,
+ Icon = 0x02,
+ Tip = 0x04,
+ State = 0x08,
+ Info = 0x10,
+ Realtime = 0x40,
+ UseLegacyToolTips = 0x80
+ }
+
+ private enum NotifyIconState : uint
+ {
+ Visible = 0x00,
+ Hidden = 0x01
+ }
+
+ public static NotificationIconHelper Create(Window window)
+ {
+ return new NotificationIconHelper(window);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ public void SetIcon(IntPtr iconHandle)
+ {
+ lock (_lock)
+ {
+ _notifyIconData.IconHandle = iconHandle;
+ WriteNotifyIconData(NotifyIconCommand.Modify, NotifyIconDataMember.Icon);
+ }
+ }
+
+ [DllImport("shell32.dll", SetLastError = true)]
+ private static extern int Shell_NotifyIcon(NotifyIconCommand notifyCommand, ref NotifyIconData notifyIconData);
+
+ private void CreateNotificationIcon()
+ {
+ lock (_lock)
+ {
+ _notifyIconData = new NotifyIconData();
+
+ _notifyIconData.cbSize = (uint)Marshal.SizeOf(_notifyIconData);
+ _notifyIconData.WindowHandle = _windowHandle;
+ _notifyIconData.TaskbarIconId = 0x0;
+ _notifyIconData.CallbackMessageId = CallbackMessage;
+ _notifyIconData.VersionOrTimeout = IconVersion;
+
+ _notifyIconData.IconHandle = IntPtr.Zero;
+
+ _notifyIconData.IconState = NotifyIconState.Hidden;
+ _notifyIconData.StateMask = NotifyIconState.Hidden;
+
+ WriteNotifyIconData(NotifyIconCommand.Add, NotifyIconDataMember.Message | NotifyIconDataMember.Icon | NotifyIconDataMember.Tip);
+ }
+ }
+
+ private void Dispose(bool disposing)
+ {
+ if (_isDisposed || !disposing) return;
+
+ lock (_lock)
+ {
+ _isDisposed = true;
+ RemoveNotificationIcon();
+ }
+ }
+
+ private void RemoveNotificationIcon() => WriteNotifyIconData(NotifyIconCommand.Delete, NotifyIconDataMember.Message);
+
+ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+ {
+ if (msg == CallbackMessage)
+ {
+ var mouseButton = MouseButton.Left;
+ var isInvoked = false;
+
+ switch ((uint)lParam)
+ {
+ case WM_LBUTTONUP:
+ isInvoked = true;
+ mouseButton = MouseButton.Left;
+ break;
+
+ case WM_MBUTTONUP:
+ isInvoked = true;
+ mouseButton = MouseButton.Middle;
+ break;
+
+ case WM_RBUTTONUP:
+ isInvoked = true;
+ mouseButton = MouseButton.Right;
+ break;
+ }
+
+ if (isInvoked)
+ {
+ IconInvoked?.Invoke(this, new NotificationIconInvokedEventArgs { MouseButton = mouseButton });
+ }
+ }
+
+ return (IntPtr)(int)PInvoke.DefWindowProc((HWND)hwnd, (uint)msg, (WPARAM)(UIntPtr)(uint)wParam, (LPARAM)lParam);
+ }
+
+ private void WriteNotifyIconData(NotifyIconCommand command, NotifyIconDataMember flags)
+ {
+ _notifyIconData.ValidMembers = flags;
+ lock (_lock)
+ {
+ Shell_NotifyIcon(command, ref _notifyIconData);
+ }
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ private struct NotifyIconData
+ {
+ public uint cbSize;
+ public IntPtr WindowHandle;
+ public uint TaskbarIconId;
+ public NotifyIconDataMember ValidMembers;
+ public uint CallbackMessageId;
+ public IntPtr IconHandle;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
+ public string ToolTipText;
+
+ public NotifyIconState IconState;
+ public NotifyIconState StateMask;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
+ public string BalloonText;
+
+ public uint VersionOrTimeout;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
+ public string BalloonTitle;
+
+ public NotifyIconBalloonType BalloonFlags;
+ public Guid TaskbarIconGuid;
+ public IntPtr CustomBalloonIconHandle;
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs b/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs
new file mode 100644
index 0000000..80737dc
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/NotificationIconInvokedEventArgs.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Windows.Input;
+
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public class NotificationIconInvokedEventArgs : EventArgs
+ {
+ public MouseButton MouseButton { get; internal set; }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/Helpers/SystemInformationHelper.cs b/NotificationFlyout.Wpf.UI/Helpers/SystemInformationHelper.cs
new file mode 100644
index 0000000..e8adbde
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/SystemInformationHelper.cs
@@ -0,0 +1,47 @@
+using Microsoft.Windows.Sdk;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public static class SystemInformationHelper
+ {
+ private const int SM_CXSCREEN = 0;
+
+ private const int SM_CYSCREEN = 1;
+
+ private const int SPI_GETWORKAREA = 48;
+
+ public static Rect VirtualScreen => GetVirtualScreen();
+
+ public static Rect WorkingArea => GetWorkingArea();
+
+ public static int GetCurrentDpi()
+ {
+ return (int)typeof(SystemParameters).GetProperty("Dpi", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null);
+ }
+
+ public static double GetCurrentDpiScaleFactor()
+ {
+ return (double)GetCurrentDpi() / 96;
+ }
+
+ private static Rect GetVirtualScreen()
+ {
+ var size = new Size(PInvoke.GetSystemMetrics(SM_CXSCREEN), PInvoke.GetSystemMetrics(SM_CYSCREEN));
+ return new Rect(0, 0, size.Width, size.Height);
+ }
+
+ private static Rect GetWorkingArea()
+ {
+ var rect = new RECT();
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, ref rect, 0);
+ return new Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ }
+
+ [DllImport("user32.dll", CharSet = CharSet.Auto)]
+ private static extern bool SystemParametersInfo(int nAction, int nParam, ref RECT rc, int nUpdate);
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Helpers/SystemSettingsHelper.cs b/NotificationFlyout.Wpf.UI/Helpers/SystemSettingsHelper.cs
new file mode 100644
index 0000000..25eb42f
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/SystemSettingsHelper.cs
@@ -0,0 +1,30 @@
+using Microsoft.Win32;
+using NotificationFlyout.Wpf.UI.Extensions;
+using System;
+
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public static class SystemSettingsHelper
+ {
+ private static readonly string PersonalizeKey = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
+
+ public static SystemTheme DefaultSystemTheme => GetDefaultSystemTheme();
+
+ private static SystemTheme GetDefaultSystemTheme()
+ {
+ return Environment.OSVersion.IsGreaterThan(OperatingSystemVersion.Windows10_1809) &&
+ ReadDword(PersonalizeKey, "SystemUsesLightTheme")
+ ? SystemTheme.Light
+ : SystemTheme.Dark;
+ }
+
+ private static bool ReadDword(string key, string valueName, int defaultValue = 0)
+ {
+ using var baseKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
+ using var subKey = baseKey.OpenSubKey(key);
+ return subKey.GetValue(valueName, defaultValue) > 0;
+ }
+
+ public static bool IsTransparencyEnabled => ReadDword(PersonalizeKey, "EnableTransparency");
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Helpers/SystemTheme.cs b/NotificationFlyout.Wpf.UI/Helpers/SystemTheme.cs
new file mode 100644
index 0000000..50b6ceb
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/SystemTheme.cs
@@ -0,0 +1,8 @@
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public enum SystemTheme
+ {
+ Dark,
+ Light
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs b/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs
new file mode 100644
index 0000000..58361dd
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/TaskbarHelper.cs
@@ -0,0 +1,118 @@
+using Microsoft.Windows.Sdk;
+using NotificationFlyout.Wpf.UI.Extensions;
+using System;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Interop;
+
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public class TaskbarHelper
+ {
+ private const string ShellTrayHandleName = "Shell_TrayWnd";
+
+ private const int SPI_SETWORKAREA = 0x002F;
+
+ private const int WSETTINGCHANGE = 0x001A;
+
+ private static readonly uint WTASKBARCREATED = PInvoke.RegisterWindowMessage("TaskbarCreated");
+
+ private TaskbarHelper(Window window)
+ {
+ var handle = window.GetHandle();
+
+ var source = HwndSource.FromHwnd(handle);
+ source.AddHook(new HwndSourceHook(WndProc));
+ }
+
+ public event EventHandler TaskbarChanged;
+
+ private enum AppBarEdge : uint
+ {
+ Left = 0,
+ Top = 1,
+ Right = 2,
+ Bottom = 3
+ }
+
+ private enum AppBarMessage : uint
+ {
+ New = 0x00000000,
+ Remove = 0x00000001,
+ QueryPos = 0x00000002,
+ SetPos = 0x00000003,
+ GetState = 0x00000004,
+ GetTaskbarPos = 0x00000005,
+ Activate = 0x00000006,
+ GetAutoHideBar = 0x00000007,
+ SetAutoHideBar = 0x00000008,
+ WindowPosChanged = 0x00000009,
+ SetState = 0x0000000A,
+ }
+
+ public static TaskbarHelper Create(Window window)
+ {
+ return new TaskbarHelper(window);
+ }
+
+ public TaskbarState GetCurrentState()
+ {
+ var handle = GetSystemTrayHandle();
+ var state = new TaskbarState
+ {
+ Screen = Screen.FromHandle(handle)
+ };
+
+ var appBarData = GetAppBarData(handle);
+ GetAppBarPosition(ref appBarData);
+
+ state.Rect = appBarData.rect.ToRect();
+ state.Position = (TaskbarPosition)appBarData.uEdge;
+
+ return state;
+ }
+
+ private static IntPtr GetSystemTrayHandle()
+ {
+ return WindowHelper.GetHandle(ShellTrayHandleName);
+ }
+
+ private AppBarData GetAppBarData(IntPtr handle)
+ {
+ return new AppBarData
+ {
+ cbSize = (uint)Marshal.SizeOf(typeof(AppBarData)),
+ hWnd = handle
+ };
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct AppBarData
+ {
+ public uint cbSize;
+ public IntPtr hWnd;
+ public uint uCallbackMessage;
+ public AppBarEdge uEdge;
+ public RECT rect;
+ public int lParam;
+ }
+
+ [DllImport("shell32.dll", SetLastError = true)]
+ private static extern IntPtr SHAppBarMessage(AppBarMessage dwMessage, ref AppBarData pData);
+
+ private void GetAppBarPosition(ref AppBarData appBarData)
+ {
+ SHAppBarMessage(AppBarMessage.GetTaskbarPos, ref appBarData);
+ }
+
+ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
+ {
+ if (msg == WTASKBARCREATED || msg == WSETTINGCHANGE && (int)wParam == SPI_SETWORKAREA)
+ {
+ TaskbarChanged?.Invoke(this, EventArgs.Empty);
+ }
+
+ return (IntPtr)(int)PInvoke.DefWindowProc((HWND)hwnd, (uint)msg, (WPARAM)(UIntPtr)(uint)wParam, (LPARAM)lParam);
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/Helpers/TaskbarPosition.cs b/NotificationFlyout.Wpf.UI/Helpers/TaskbarPosition.cs
new file mode 100644
index 0000000..6cb41bf
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/TaskbarPosition.cs
@@ -0,0 +1,11 @@
+namespace NotificationFlyout.Wpf.UI
+{
+
+ public enum TaskbarPosition
+ {
+ Left = 0,
+ Top = 1,
+ Right = 2,
+ Bottom = 3
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/Helpers/TaskbarState.cs b/NotificationFlyout.Wpf.UI/Helpers/TaskbarState.cs
new file mode 100644
index 0000000..7e3e020
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/TaskbarState.cs
@@ -0,0 +1,11 @@
+using System.Windows;
+
+namespace NotificationFlyout.Wpf.UI
+{
+ public struct TaskbarState
+ {
+ public TaskbarPosition Position;
+ public Rect Rect;
+ public Screen Screen;
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs b/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs
new file mode 100644
index 0000000..4e741cd
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Helpers/WindowHelper.cs
@@ -0,0 +1,18 @@
+using Microsoft.Windows.Sdk;
+using System;
+
+namespace NotificationFlyout.Wpf.UI.Helpers
+{
+ public class WindowHelper
+ {
+ public static IntPtr GetHandle(string windowName)
+ {
+ return PInvoke.FindWindow(windowName, null);
+ }
+
+ public static uint GetDpi(IntPtr handle)
+ {
+ return PInvoke.GetDpiForWindow((HWND)handle);
+ }
+ }
+}
diff --git a/NotificationFlyout.Wpf.UI/NativeMethods.txt b/NotificationFlyout.Wpf.UI/NativeMethods.txt
new file mode 100644
index 0000000..c243fa0
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/NativeMethods.txt
@@ -0,0 +1,11 @@
+Shell_NotifyIcon
+GetDpiForWindow
+FindWindow
+GetSystemMetricsForDpi
+DefWindowProcW
+GetSystemMetrics
+MonitorFromWindow
+RegisterWindowMessage
+FindWindow
+SHAppBarMessage
+SetWindowPos
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj b/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj
new file mode 100644
index 0000000..0da0fef
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/NotificationFlyout.Wpf.UI.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netcoreapp3.1
+ true
+ 9.0
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
diff --git a/NotificationFlyout.Wpf.UI/Properties/AssemblyInfo.cs b/NotificationFlyout.Wpf.UI/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4f943de
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Properties/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
\ No newline at end of file
diff --git a/NotificationFlyout.Wpf.UI/Screen.cs b/NotificationFlyout.Wpf.UI/Screen.cs
new file mode 100644
index 0000000..9a294df
--- /dev/null
+++ b/NotificationFlyout.Wpf.UI/Screen.cs
@@ -0,0 +1,114 @@
+using Microsoft.Windows.Sdk;
+using NotificationFlyout.Wpf.UI.Helpers;
+using System;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+namespace NotificationFlyout.Wpf.UI
+{
+ public class Screen
+ {
+ private const int CCHDEVICENAME = 32;
+ private const int PRIMARY_MONITOR = unchecked((int)0xBAADF00D);
+ private const int SM_CMONITORS = 80;
+ private static readonly bool _multiMonitorSupport;
+
+ private readonly IntPtr _monitorHandle;
+
+ static Screen()
+ {
+ _multiMonitorSupport = PInvoke.GetSystemMetrics(SM_CMONITORS) != 0;
+ }
+
+ internal Screen(IntPtr monitorHandle)
+ {
+ if (!_multiMonitorSupport || monitorHandle == (IntPtr)PRIMARY_MONITOR)
+ {
+ Bounds = SystemInformationHelper.VirtualScreen;
+ Primary = true;
+ DeviceName = "DISPLAY";
+ }
+ else
+ {
+ var monitorData = GetMonitorData(monitorHandle);
+
+ Bounds = new Rect(monitorData.MonitorRect.left, monitorData.MonitorRect.top, monitorData.MonitorRect.right - monitorData.MonitorRect.left, monitorData.MonitorRect.bottom - monitorData.MonitorRect.top);
+ Primary = (monitorData.Flags & (int)MonitorFlag.MONITOR_DEFAULTTOPRIMARY) != 0;
+ DeviceName = monitorData.DeviceName;
+ }
+
+ _monitorHandle = monitorHandle;
+ }
+
+ private enum MonitorFlag : uint
+ {
+ MONITOR_DEFAULTTONULL = 0,
+ MONITOR_DEFAULTTOPRIMARY = 1,
+ MONITOR_DEFAULTTONEAREST = 2
+ }
+
+ public Rect Bounds { get; }
+
+ public string DeviceName { get; }
+
+ public bool Primary { get; }
+
+ public Rect WorkingArea => GetWorkingArea();
+
+ public static Screen FromHandle(IntPtr handle)
+ {
+ return _multiMonitorSupport ? new Screen(PInvoke.MonitorFromWindow((HWND)handle, (uint)MonitorFlag.MONITOR_DEFAULTTONEAREST)) : new Screen((IntPtr)PRIMARY_MONITOR);
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Screen monitor)
+ {
+ if (_monitorHandle == monitor._monitorHandle)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return (int)_monitorHandle;
+ }
+
+ [DllImport("user32.dll", EntryPoint = "GetMonitorInfo", CharSet = CharSet.Auto, SetLastError = true)]
+ private static extern bool GetMonitorInfoEx(IntPtr hMonitor, ref MonitorData lpmi);
+
+ private MonitorData GetMonitorData(IntPtr monitorHandle)
+ {
+ var monitorData = new MonitorData();
+ monitorData.Size = Marshal.SizeOf(monitorData);
+ GetMonitorInfoEx(monitorHandle, ref monitorData);
+
+ return monitorData;
+ }
+ private Rect GetWorkingArea()
+ {
+ if (!_multiMonitorSupport || _monitorHandle == (IntPtr)PRIMARY_MONITOR)
+ {
+ return SystemInformationHelper.WorkingArea;
+ }
+
+ var monitorData = GetMonitorData(_monitorHandle);
+ return new Rect(monitorData.WorkAreaRect.left, monitorData.WorkAreaRect.top, monitorData.WorkAreaRect.right - monitorData.WorkAreaRect.left, monitorData.WorkAreaRect.bottom - monitorData.WorkAreaRect.top);
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ private struct MonitorData
+ {
+ public int Size;
+ public RECT MonitorRect;
+ public RECT WorkAreaRect;
+ public uint Flags;
+
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
+ public string DeviceName;
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.XamlHost/App.xaml b/NotificationFlyout.XamlHost/App.xaml
new file mode 100644
index 0000000..5371cf7
--- /dev/null
+++ b/NotificationFlyout.XamlHost/App.xaml
@@ -0,0 +1,6 @@
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.XamlHost/App.xaml.cs b/NotificationFlyout.XamlHost/App.xaml.cs
new file mode 100644
index 0000000..893892e
--- /dev/null
+++ b/NotificationFlyout.XamlHost/App.xaml.cs
@@ -0,0 +1,12 @@
+using Microsoft.Toolkit.Win32.UI.XamlHost;
+
+namespace NotificationFlyout.XamlHost
+{
+ public sealed partial class App : XamlApplication
+ {
+ public App()
+ {
+ Initialize();
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout.XamlHost/Assets/LockScreenLogo.scale-200.png b/NotificationFlyout.XamlHost/Assets/LockScreenLogo.scale-200.png
new file mode 100644
index 0000000..735f57a
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/LockScreenLogo.scale-200.png differ
diff --git a/NotificationFlyout.XamlHost/Assets/SplashScreen.scale-200.png b/NotificationFlyout.XamlHost/Assets/SplashScreen.scale-200.png
new file mode 100644
index 0000000..023e7f1
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/SplashScreen.scale-200.png differ
diff --git a/NotificationFlyout.XamlHost/Assets/Square150x150Logo.scale-200.png b/NotificationFlyout.XamlHost/Assets/Square150x150Logo.scale-200.png
new file mode 100644
index 0000000..af49fec
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/Square150x150Logo.scale-200.png differ
diff --git a/NotificationFlyout.XamlHost/Assets/Square44x44Logo.scale-200.png b/NotificationFlyout.XamlHost/Assets/Square44x44Logo.scale-200.png
new file mode 100644
index 0000000..ce342a2
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/Square44x44Logo.scale-200.png differ
diff --git a/NotificationFlyout.XamlHost/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/NotificationFlyout.XamlHost/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
new file mode 100644
index 0000000..f6c02ce
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/Square44x44Logo.targetsize-24_altform-unplated.png differ
diff --git a/NotificationFlyout.XamlHost/Assets/StoreLogo.png b/NotificationFlyout.XamlHost/Assets/StoreLogo.png
new file mode 100644
index 0000000..7385b56
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/StoreLogo.png differ
diff --git a/NotificationFlyout.XamlHost/Assets/Wide310x150Logo.scale-200.png b/NotificationFlyout.XamlHost/Assets/Wide310x150Logo.scale-200.png
new file mode 100644
index 0000000..288995b
Binary files /dev/null and b/NotificationFlyout.XamlHost/Assets/Wide310x150Logo.scale-200.png differ
diff --git a/NotificationFlyout.XamlHost/NotificationFlyout.XamlHost.csproj b/NotificationFlyout.XamlHost/NotificationFlyout.XamlHost.csproj
new file mode 100644
index 0000000..e3498f8
--- /dev/null
+++ b/NotificationFlyout.XamlHost/NotificationFlyout.XamlHost.csproj
@@ -0,0 +1,170 @@
+
+
+
+
+ Debug
+ x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}
+ AppContainerExe
+ Properties
+ NotificationFlyout.XamlHost
+ NotificationFlyout.XamlHost
+ en-US
+ UAP
+ 10.0.19041.0
+ 10.0.19041.0
+ 14
+ 512
+ {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ true
+ false
+
+
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ x86
+ false
+ prompt
+ true
+
+
+ bin\x86\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ x86
+ false
+ prompt
+ true
+ true
+
+
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ ARM
+ false
+ prompt
+ true
+
+
+ bin\ARM\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ ARM
+ false
+ prompt
+ true
+ true
+
+
+ true
+ bin\ARM64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ ARM64
+ false
+ prompt
+ true
+ true
+
+
+ bin\ARM64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ ARM64
+ false
+ prompt
+ true
+ true
+
+
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ x64
+ false
+ prompt
+ true
+
+
+ bin\x64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ x64
+ false
+ prompt
+ true
+ true
+
+
+ PackageReference
+
+
+
+ App.xaml
+
+
+
+
+
+ Designer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MSBuild:Compile
+ Designer
+
+
+
+
+ 6.2.11
+
+
+ 6.1.2
+
+
+
+
+ {9987b132-e42c-401a-9ad5-e62529faca40}
+ NotificationFlyout.Uwp.UI.Controls
+
+
+
+ 14.0
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.XamlHost/Package.appxmanifest b/NotificationFlyout.XamlHost/Package.appxmanifest
new file mode 100644
index 0000000..9e7b83d
--- /dev/null
+++ b/NotificationFlyout.XamlHost/Package.appxmanifest
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+ NotificationFlyout.XamlHost
+ dan
+ Assets\StoreLogo.png
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.XamlHost/Properties/AssemblyInfo.cs b/NotificationFlyout.XamlHost/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..abc3bb1
--- /dev/null
+++ b/NotificationFlyout.XamlHost/Properties/AssemblyInfo.cs
@@ -0,0 +1,28 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NotificationFlyout.XamlHost")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NotificationFlyout.XamlHost")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/NotificationFlyout.XamlHost/Properties/Default.rd.xml b/NotificationFlyout.XamlHost/Properties/Default.rd.xml
new file mode 100644
index 0000000..7454086
--- /dev/null
+++ b/NotificationFlyout.XamlHost/Properties/Default.rd.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout.sln b/NotificationFlyout.sln
new file mode 100644
index 0000000..0d5c68e
--- /dev/null
+++ b/NotificationFlyout.sln
@@ -0,0 +1,219 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30914.41
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Foundation", "NotificationFlyout.Foundation\NotificationFlyout.Foundation.csproj", "{8CF304C1-38D4-4D16-B99C-71353E8DD477}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.XamlHost", "NotificationFlyout.XamlHost\NotificationFlyout.XamlHost.csproj", "{95D6E127-BC04-4591-ACFF-FB35BBB64884}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Tray", "NotificationFlyout.Tray\NotificationFlyout.Tray.csproj", "{B5B09576-6447-4146-B544-FB6000587D8B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI.Controls", "NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj", "{0A782234-DC9F-4C4A-8820-FC640B03D233}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.Uwp.UI.Controls", "NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj", "{9987B132-E42C-401A-9AD5-E62529FACA40}"
+EndProject
+Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "NotificationFlyout.Package", "NotificationFlyout.Package\NotificationFlyout.Package.wapproj", "{46FF88D3-C2C7-419B-94F6-1AC01307C31A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI", "NotificationFlyout.Wpf.UI\NotificationFlyout.Wpf.UI.csproj", "{29430194-7EDE-4C33-AF59-CE121F48F66E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.Sample", "NotificationFlyout.Sample\NotificationFlyout.Sample.csproj", "{675B9345-F416-44EF-8154-B7F6943877FA}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|ARM = Debug|ARM
+ Debug|ARM64 = Debug|ARM64
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|ARM = Release|ARM
+ Release|ARM64 = Release|ARM64
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|ARM.Build.0 = Debug|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|x64.ActiveCfg = Debug|x64
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|x64.Build.0 = Debug|x64
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|x86.ActiveCfg = Debug|x64
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Debug|x86.Build.0 = Debug|x64
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|ARM.ActiveCfg = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|ARM.Build.0 = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|ARM64.Build.0 = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|x64.ActiveCfg = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|x64.Build.0 = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|x86.ActiveCfg = Release|Any CPU
+ {8CF304C1-38D4-4D16-B99C-71353E8DD477}.Release|x86.Build.0 = Release|Any CPU
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|ARM.ActiveCfg = Debug|ARM
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|ARM.Build.0 = Debug|ARM
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|ARM.Deploy.0 = Debug|ARM
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|ARM64.Build.0 = Debug|ARM64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|x64.ActiveCfg = Debug|x64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|x64.Build.0 = Debug|x64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|x64.Deploy.0 = Debug|x64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|x86.ActiveCfg = Debug|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|x86.Build.0 = Debug|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Debug|x86.Deploy.0 = Debug|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|Any CPU.ActiveCfg = Release|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|ARM.ActiveCfg = Release|ARM
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|ARM.Build.0 = Release|ARM
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|ARM.Deploy.0 = Release|ARM
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|ARM64.ActiveCfg = Release|ARM64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|ARM64.Build.0 = Release|ARM64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|ARM64.Deploy.0 = Release|ARM64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|x64.ActiveCfg = Release|x64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|x64.Build.0 = Release|x64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|x64.Deploy.0 = Release|x64
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|x86.ActiveCfg = Release|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|x86.Build.0 = Release|x86
+ {95D6E127-BC04-4591-ACFF-FB35BBB64884}.Release|x86.Deploy.0 = Release|x86
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|ARM.Build.0 = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|x64.ActiveCfg = Debug|x64
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|x64.Build.0 = Debug|x64
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Debug|x86.Build.0 = Debug|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|ARM.ActiveCfg = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|ARM.Build.0 = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|ARM64.Build.0 = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|x64.ActiveCfg = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|x64.Build.0 = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|x86.ActiveCfg = Release|Any CPU
+ {B5B09576-6447-4146-B544-FB6000587D8B}.Release|x86.Build.0 = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|ARM.Build.0 = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|x64.ActiveCfg = Debug|x64
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|x64.Build.0 = Debug|x64
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Debug|x86.Build.0 = Debug|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|ARM.ActiveCfg = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|ARM.Build.0 = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|ARM64.Build.0 = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|x64.ActiveCfg = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|x64.Build.0 = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|x86.ActiveCfg = Release|Any CPU
+ {0A782234-DC9F-4C4A-8820-FC640B03D233}.Release|x86.Build.0 = Release|Any CPU
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|ARM.ActiveCfg = Debug|ARM
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|ARM.Build.0 = Debug|ARM
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|ARM64.Build.0 = Debug|ARM64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|x64.ActiveCfg = Debug|x64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|x64.Build.0 = Debug|x64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|x86.ActiveCfg = Debug|x86
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Debug|x86.Build.0 = Debug|x86
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|ARM.ActiveCfg = Release|ARM
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|ARM.Build.0 = Release|ARM
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|ARM64.ActiveCfg = Release|ARM64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|ARM64.Build.0 = Release|ARM64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|x64.ActiveCfg = Release|x64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|x64.Build.0 = Release|x64
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|x86.ActiveCfg = Release|x86
+ {9987B132-E42C-401A-9AD5-E62529FACA40}.Release|x86.Build.0 = Release|x86
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|ARM.ActiveCfg = Debug|ARM
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|ARM.Build.0 = Debug|ARM
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|ARM.Deploy.0 = Debug|ARM
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|ARM64.Build.0 = Debug|ARM64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|ARM64.Deploy.0 = Debug|ARM64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|x64.ActiveCfg = Debug|x64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|x64.Build.0 = Debug|x64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|x64.Deploy.0 = Debug|x64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|x86.ActiveCfg = Debug|x86
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|x86.Build.0 = Debug|x86
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Debug|x86.Deploy.0 = Debug|x86
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|ARM.ActiveCfg = Release|ARM
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|ARM.Build.0 = Release|ARM
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|ARM.Deploy.0 = Release|ARM
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|ARM64.ActiveCfg = Release|ARM64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|ARM64.Build.0 = Release|ARM64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|ARM64.Deploy.0 = Release|ARM64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|x64.ActiveCfg = Release|x64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|x64.Build.0 = Release|x64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|x64.Deploy.0 = Release|x64
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|x86.ActiveCfg = Release|x86
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|x86.Build.0 = Release|x86
+ {46FF88D3-C2C7-419B-94F6-1AC01307C31A}.Release|x86.Deploy.0 = Release|x86
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|ARM.Build.0 = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|x64.Build.0 = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Debug|x86.Build.0 = Debug|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|ARM.ActiveCfg = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|ARM.Build.0 = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|ARM64.Build.0 = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x64.ActiveCfg = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x64.Build.0 = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x86.ActiveCfg = Release|Any CPU
+ {29430194-7EDE-4C33-AF59-CE121F48F66E}.Release|x86.Build.0 = Release|Any CPU
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|ARM.ActiveCfg = Debug|ARM
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|ARM.Build.0 = Debug|ARM
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|ARM64.ActiveCfg = Debug|ARM64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|ARM64.Build.0 = Debug|ARM64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|x64.ActiveCfg = Debug|x64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|x64.Build.0 = Debug|x64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|x86.ActiveCfg = Debug|x86
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Debug|x86.Build.0 = Debug|x86
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|ARM.ActiveCfg = Release|ARM
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|ARM.Build.0 = Release|ARM
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|ARM64.ActiveCfg = Release|ARM64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|ARM64.Build.0 = Release|ARM64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|x64.ActiveCfg = Release|x64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|x64.Build.0 = Release|x64
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|x86.ActiveCfg = Release|x86
+ {675B9345-F416-44EF-8154-B7F6943877FA}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {EDFFB261-AD00-4C68-BF55-D5CED5BE0039}
+ EndGlobalSection
+EndGlobal
diff --git a/NotificationFlyout/MyUserControl1.xaml b/NotificationFlyout/MyUserControl1.xaml
new file mode 100644
index 0000000..f99c718
--- /dev/null
+++ b/NotificationFlyout/MyUserControl1.xaml
@@ -0,0 +1,14 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout/MyUserControl1.xaml.cs b/NotificationFlyout/MyUserControl1.xaml.cs
new file mode 100644
index 0000000..ecf588e
--- /dev/null
+++ b/NotificationFlyout/MyUserControl1.xaml.cs
@@ -0,0 +1,14 @@
+using Windows.UI.Xaml.Controls;
+
+// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
+
+namespace NotificationFlyout
+{
+ public sealed partial class MyUserControl1 : UserControl
+ {
+ public MyUserControl1()
+ {
+ this.InitializeComponent();
+ }
+ }
+}
\ No newline at end of file
diff --git a/NotificationFlyout/NotificationFlyout.csproj b/NotificationFlyout/NotificationFlyout.csproj
new file mode 100644
index 0000000..2275b53
--- /dev/null
+++ b/NotificationFlyout/NotificationFlyout.csproj
@@ -0,0 +1,157 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {08C84B28-D5A2-4C77-BA72-5B2B4674DEFC}
+ Library
+ Properties
+ NotificationFlyout
+ NotificationFlyout
+ en-US
+ UAP
+ 10.0.19041.0
+ 10.0.19041.0
+ 14
+ 512
+ {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ prompt
+ 4
+
+
+ x86
+ true
+ bin\x86\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ x86
+ bin\x86\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ ARM
+ true
+ bin\ARM\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ ARM
+ bin\ARM\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ ARM64
+ true
+ bin\ARM64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ ARM64
+ bin\ARM64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ x64
+ true
+ bin\x64\Debug\
+ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP
+ ;2008
+ full
+ false
+ prompt
+
+
+ x64
+ bin\x64\Release\
+ TRACE;NETFX_CORE;WINDOWS_UWP
+ true
+ ;2008
+ pdbonly
+ false
+ prompt
+
+
+ PackageReference
+
+
+
+ MyUserControl1.xaml
+
+
+
+
+
+
+ 6.2.11
+
+
+
+
+ {9987b132-e42c-401a-9ad5-e62529faca40}
+ NotificationFlyout.Uwp.UI.Controls
+
+
+
+
+ Designer
+ MSBuild:Compile
+
+
+
+ 14.0
+
+
+
+
\ No newline at end of file
diff --git a/NotificationFlyout/Properties/AssemblyInfo.cs b/NotificationFlyout/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..208104e
--- /dev/null
+++ b/NotificationFlyout/Properties/AssemblyInfo.cs
@@ -0,0 +1,28 @@
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("NotificationFlyout")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("NotificationFlyout")]
+[assembly: AssemblyCopyright("Copyright © 2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: ComVisible(false)]
\ No newline at end of file
diff --git a/NotificationFlyout/Properties/NotificationFlyout.rd.xml b/NotificationFlyout/Properties/NotificationFlyout.rd.xml
new file mode 100644
index 0000000..0fe561c
--- /dev/null
+++ b/NotificationFlyout/Properties/NotificationFlyout.rd.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
\ No newline at end of file