23 Commits

Author SHA1 Message Date
Daniel Clark 10499366d6 further work to get placement in a multi mon setup working properly 2021-03-02 20:36:14 +00:00
Daniel Clark 24bdc3caa2 Continue to tweak offset 2021-03-01 20:36:31 +00:00
Daniel Clark ab7ea6415d Remove test code for resizing until a better solution comes up 2021-03-01 17:20:10 +00:00
Daniel Clark 0a6b227fc6 fixed issue with DPI not updating 2021-03-01 16:02:58 +00:00
Daniel Clark dd92d25d23 Amend how we hide the xaml window 2021-02-28 18:48:49 +00:00
Daniel Clark b815985963 fix issue with DPI 2021-02-28 18:45:12 +00:00
Daniel Clark 04de82cda0 Allow placement to be updated at run time 2021-02-27 20:27:56 +00:00
Daniel Clark efc2f75d85 implemented FullRight placement mode 2021-02-27 20:19:58 +00:00
Daniel Clark 47540457b8 show popup first and then set the placement... this is to ensure we are getting the correct size 2021-02-27 17:40:05 +00:00
Daniel Clark 1800eefd5a Amend how we hide via deactivation as the user may still want to call Hide explicitly while having IsLightDismissedEnabled set to false 2021-02-27 15:38:09 +00:00
Daniel Clark f9c688aa02 Added ability to keep the flyout open on the desktop which can be set via IsLightDismissEnabled DP 2021-02-27 15:24:47 +00:00
Daniel Clark 8e334912b9 Added offset value to offset the popup position by 1px 2021-02-27 14:18:32 +00:00
Daniel Clark 5db230c83c re-wired opened and closed events 2021-02-27 12:03:36 +00:00
Daniel Clark 240609270e fixed issue with margin 2021-02-27 11:57:23 +00:00
Daniel Clark 737dbe9b32 Major refactor to use Popup replacing the Flyout. This will allow for future enhancements. 2021-02-26 20:48:10 +00:00
Daniel Clark c408eafdde [WIP] Positioning of popup 2021-02-26 16:21:23 +00:00
Daniel Clark f0b42d1551 [WIP] Move over to a popup 2021-02-26 14:34:13 +00:00
Daniel Clark d25744a9f4 Added ability to set Auto or Right flyout placement 2021-02-25 17:39:19 +00:00
Daniel Clark 36f2953fd4 Added NotificationFlyoutPlacement enum 2021-02-25 15:08:45 +00:00
Daniel Clark bc42e0cff1 Remove max width and height from flyout style 2021-02-25 15:02:42 +00:00
Daniel Clark d48d0bd590 Added showcase section to read me 2021-02-15 22:50:40 +00:00
Daniel Clark 6751bc914e Update readme 2021-02-15 22:37:00 +00:00
Daniel Clark ac1ace291c Remove steps for setting notification icons 2021-02-15 22:35:51 +00:00
45 changed files with 1090 additions and 1079 deletions
+8 -6
View File
@@ -4,6 +4,12 @@ A Notification Flyout that looks and feels exactly like the native Volume, Netwo
# Demo #
[![](http://img.youtube.com/vi/8EoZ4pGWTkY/0.jpg)](http://www.youtube.com/watch?v=8EoZ4pGWTkY "Notification flyout demo")
# Show case #
[NotificationFlyout.NowPlaying](https://github.com/TheXamlGuy/NotificationFlyout.NowPlaying)
![](https://github.com/TheXamlGuy/NotificationFlyout.NowPlaying/blob/master/wip_concept.png)
# Getting started #
Many parts of this guide refers to the [Host a custom WinRT XAML control in a WPF app using XAML Islands](https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/host-custom-control-with-xaml-islands) article. If in doubt, refer to the article, or post an issue on this repro.
@@ -34,15 +40,13 @@ namespace MyUWPApp
}
```
5. In the UWP app project, install the [TheXamlGuy.NotificationFlyout.Uwp.UI.Controls](https://www.nuget.org/packages/TheXamlGuy.NotificationFlyout.Uwp.UI.Controls/) NuGet package (latest stable version).
3. Open the `MainPage.xaml` file and replace the contents of this file with the following XAML. Replace `MyUWPApp` with the namespace of your UWP app project.
6. Open the `MainPage.xaml` file and replace the contents of this file with the following XAML. Replace `MyUWPApp` with the namespace of your UWP app project.
```xaml
<controls:NotificationFlyout
x:Class="MyUWPApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls"
IconSource="/Assets/Icon.ico"
LightIconSource="/Assets/Icon-Light.ico">
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls">
<Grid Width="400" Height="500">
<Button
HorizontalAlignment="Center"
@@ -51,8 +55,6 @@ namespace MyUWPApp
</Grid>
</controls:NotificationFlyout>
```
5. In the UWP app project, add two icons (.ico) to the Assets folder.
6. Replace the values of `IconSource` and `LightIconSource` with the paths of the icons that you have added to your Assets folder.
7. Clean the UWP app project and then build it.
## Create a WPF project ##
@@ -4,18 +4,22 @@
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<Platforms>AnyCPU;x64</Platforms>
<StartupObject>NotificationFlyoutSample.Host.Program</StartupObject>
<AssetTargetFallback>uap10.0.19041</AssetTargetFallback>
<Platforms>x64</Platforms>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.XamlHost" Version="6.1.2" />
<PackageReference Include="Microsoft.Win32.Registry" Version="6.0.0-preview.1.21102.12" />
<PackageReference Include="System.Drawing.Common" Version="6.0.0-preview.1.21102.12" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj" />
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj" />
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls.csproj" />
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls.csproj" />
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Wpf.UI\TheXamlGuy.NotificationFlyout.Wpf.UI.csproj" />
<ProjectReference Include="..\NotificationFlyoutSample\NotificationFlyoutSample.csproj" />
@@ -15,6 +15,7 @@ namespace NotificationFlyoutSample.Host
{
Flyout = new SampleFlyout()
};
app.Run();
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '15.0'">
<VisualStudioVersion>15.0</VisualStudioVersion>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|AnyCPU">
<Configuration>Debug</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|AnyCPU">
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup>
<WapProjPath Condition="'$(WapProjPath)'==''">$(MSBuildExtensionsPath)\Microsoft\DesktopBridge\</WapProjPath>
</PropertyGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.props" />
<PropertyGroup>
<ProjectGuid>faa7e8e0-032d-4c2a-bab6-6e0eed3d5a6d</ProjectGuid>
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\NotificationFlyoutSample.Launcher\NotificationFlyoutSample.Launcher.csproj</EntryPointProjectUniqueName>
</PropertyGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
</ItemGroup>
<ItemGroup>
<Content Include="Images\SplashScreen.scale-200.png" />
<Content Include="Images\LockScreenLogo.scale-200.png" />
<Content Include="Images\Square150x150Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.scale-200.png" />
<Content Include="Images\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Images\StoreLogo.png" />
<Content Include="Images\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<Import Project="$(WapProjPath)\Microsoft.DesktopBridge.targets" />
<ItemGroup>
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.19041.8" PrivateAssets="all" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NotificationFlyoutSample.Launcher\NotificationFlyoutSample.Launcher.csproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>
</Project>
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="541ef8e5-df48-4089-bae4-7851e8c5d592"
Publisher="CN=Daniel Clark"
Version="1.0.0.0" />
<Properties>
<DisplayName>NotificationFlyoutSample.Package</DisplayName>
<PublisherDisplayName>Daniel Clark</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="NotificationFlyoutSample.Package"
Description="NotificationFlyoutSample.Package"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>
+126 -126
View File
@@ -10,17 +10,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyoutSample.Host", "NotificationFlyoutSample.Host\NotificationFlyoutSample.Host.csproj", "{591F26F7-C057-434A-B612-AEB37B1234AE}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyoutSample.Launcher", "NotificationFlyoutSample.Launcher\NotificationFlyoutSample.Launcher.csproj", "{5EDD254A-3F8E-4825-B806-5C230488E192}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Shared.UI", "..\src\TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj", "{38E34B61-E389-4EE1-8D5E-5372568DE982}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Common", "..\src\TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj", "{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Uwp.UI.Controls", "..\src\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls.csproj", "{ACA2CC23-A9AE-427F-A900-ED75A96698F4}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Shared.UI", "..\src\TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj", "{875E7116-3A9B-4CBE-B6D0-20818DB77280}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Wpf.UI.Controls", "..\src\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls.csproj", "{BE3B1281-CD44-4291-BE1D-33FC13E61E06}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Uwp.UI.Controls", "..\src\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls.csproj", "{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Wpf.UI", "..\src\TheXamlGuy.NotificationFlyout.Wpf.UI\TheXamlGuy.NotificationFlyout.Wpf.UI.csproj", "{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Wpf.UI", "..\src\TheXamlGuy.NotificationFlyout.Wpf.UI\TheXamlGuy.NotificationFlyout.Wpf.UI.csproj", "{F6040CB8-83EE-47B9-8DD7-DF43CD555956}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Common", "..\src\TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj", "{293834F2-4A99-4C92-A165-7C617D98FCC7}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Wpf.UI.Controls", "..\src\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls.csproj", "{66433384-A10C-44A5-B734-400990A569F0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -63,126 +63,126 @@ Global
{2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}.Release|x86.ActiveCfg = Release|x86
{2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}.Release|x86.Build.0 = Release|x86
{2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}.Release|x86.Deploy.0 = Release|x86
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|Any CPU.ActiveCfg = Debug|x64
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|Any CPU.Build.0 = Debug|x64
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|ARM.ActiveCfg = Debug|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|ARM.Build.0 = Debug|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|ARM64.Build.0 = Debug|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|x64.ActiveCfg = Debug|x64
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|x64.Build.0 = Debug|x64
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|x86.ActiveCfg = Debug|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Debug|x86.Build.0 = Debug|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|Any CPU.Build.0 = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|ARM.ActiveCfg = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|ARM.Build.0 = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|ARM64.ActiveCfg = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|ARM64.Build.0 = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|x64.ActiveCfg = Release|x64
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|x64.Build.0 = Release|x64
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|x86.ActiveCfg = Release|Any CPU
{591F26F7-C057-434A-B612-AEB37B1234AE}.Release|x86.Build.0 = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|Any CPU.Build.0 = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|ARM.ActiveCfg = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|ARM.Build.0 = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|ARM64.Build.0 = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|x64.ActiveCfg = Debug|x64
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|x64.Build.0 = Debug|x64
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|x86.ActiveCfg = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Debug|x86.Build.0 = Debug|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|Any CPU.ActiveCfg = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|Any CPU.Build.0 = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|ARM.ActiveCfg = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|ARM.Build.0 = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|ARM64.ActiveCfg = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|ARM64.Build.0 = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|x64.ActiveCfg = Release|x64
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|x64.Build.0 = Release|x64
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|x86.ActiveCfg = Release|Any CPU
{38E34B61-E389-4EE1-8D5E-5372568DE982}.Release|x86.Build.0 = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|ARM.ActiveCfg = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|ARM.Build.0 = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|ARM64.Build.0 = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|x64.ActiveCfg = Debug|x64
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|x64.Build.0 = Debug|x64
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|x86.ActiveCfg = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Debug|x86.Build.0 = Debug|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|Any CPU.Build.0 = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|ARM.ActiveCfg = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|ARM.Build.0 = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|ARM64.ActiveCfg = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|ARM64.Build.0 = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|x64.ActiveCfg = Release|x64
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|x64.Build.0 = Release|x64
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|x86.ActiveCfg = Release|Any CPU
{ACA2CC23-A9AE-427F-A900-ED75A96698F4}.Release|x86.Build.0 = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|ARM.ActiveCfg = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|ARM.Build.0 = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|ARM64.Build.0 = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|x64.ActiveCfg = Debug|x64
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|x64.Build.0 = Debug|x64
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|x86.ActiveCfg = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Debug|x86.Build.0 = Debug|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|Any CPU.Build.0 = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|ARM.ActiveCfg = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|ARM.Build.0 = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|ARM64.ActiveCfg = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|ARM64.Build.0 = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|x64.ActiveCfg = Release|x64
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|x64.Build.0 = Release|x64
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|x86.ActiveCfg = Release|Any CPU
{BE3B1281-CD44-4291-BE1D-33FC13E61E06}.Release|x86.Build.0 = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|ARM.Build.0 = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|ARM64.Build.0 = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|x64.ActiveCfg = Debug|x64
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|x64.Build.0 = Debug|x64
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|x86.ActiveCfg = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Debug|x86.Build.0 = Debug|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|Any CPU.Build.0 = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|ARM.ActiveCfg = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|ARM.Build.0 = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|ARM64.ActiveCfg = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|ARM64.Build.0 = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|x64.ActiveCfg = Release|x64
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|x64.Build.0 = Release|x64
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|x86.ActiveCfg = Release|Any CPU
{A38BA7F7-5FEC-49F2-9FEB-F80AFE5934AF}.Release|x86.Build.0 = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|ARM.Build.0 = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|ARM64.Build.0 = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|x64.ActiveCfg = Debug|x64
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|x64.Build.0 = Debug|x64
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|x86.ActiveCfg = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Debug|x86.Build.0 = Debug|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|Any CPU.Build.0 = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|ARM.ActiveCfg = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|ARM.Build.0 = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|ARM64.ActiveCfg = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|ARM64.Build.0 = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|x64.ActiveCfg = Release|x64
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|x64.Build.0 = Release|x64
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|x86.ActiveCfg = Release|Any CPU
{293834F2-4A99-4C92-A165-7C617D98FCC7}.Release|x86.Build.0 = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|ARM.Build.0 = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|ARM64.Build.0 = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|x64.ActiveCfg = Debug|x64
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|x64.Build.0 = Debug|x64
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|x86.ActiveCfg = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Debug|x86.Build.0 = Debug|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|Any CPU.Build.0 = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|ARM.ActiveCfg = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|ARM.Build.0 = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|ARM64.ActiveCfg = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|ARM64.Build.0 = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|x64.ActiveCfg = Release|x64
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|x64.Build.0 = Release|x64
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|x86.ActiveCfg = Release|Any CPU
{5EDD254A-3F8E-4825-B806-5C230488E192}.Release|x86.Build.0 = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|ARM.Build.0 = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|ARM64.Build.0 = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|x64.ActiveCfg = Debug|x64
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|x64.Build.0 = Debug|x64
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|x86.ActiveCfg = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Debug|x86.Build.0 = Debug|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|Any CPU.Build.0 = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|ARM.ActiveCfg = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|ARM.Build.0 = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|ARM64.ActiveCfg = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|ARM64.Build.0 = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|x64.ActiveCfg = Release|x64
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|x64.Build.0 = Release|x64
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|x86.ActiveCfg = Release|Any CPU
{5EE122E5-AFD9-4B03-A98D-34CBB0B3B3F0}.Release|x86.Build.0 = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|Any CPU.Build.0 = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|ARM.ActiveCfg = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|ARM.Build.0 = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|ARM64.Build.0 = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|x64.ActiveCfg = Debug|x64
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|x64.Build.0 = Debug|x64
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|x86.ActiveCfg = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Debug|x86.Build.0 = Debug|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|Any CPU.ActiveCfg = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|Any CPU.Build.0 = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|ARM.ActiveCfg = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|ARM.Build.0 = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|ARM64.ActiveCfg = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|ARM64.Build.0 = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|x64.ActiveCfg = Release|x64
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|x64.Build.0 = Release|x64
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|x86.ActiveCfg = Release|Any CPU
{875E7116-3A9B-4CBE-B6D0-20818DB77280}.Release|x86.Build.0 = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|ARM.Build.0 = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|ARM64.Build.0 = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|x64.ActiveCfg = Debug|x64
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|x64.Build.0 = Debug|x64
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|x86.ActiveCfg = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Debug|x86.Build.0 = Debug|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|Any CPU.Build.0 = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|ARM.ActiveCfg = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|ARM.Build.0 = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|ARM64.ActiveCfg = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|ARM64.Build.0 = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|x64.ActiveCfg = Release|x64
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|x64.Build.0 = Release|x64
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|x86.ActiveCfg = Release|Any CPU
{0C268B32-CED0-4F79-9CB0-B7AE84BE9EC8}.Release|x86.Build.0 = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|ARM.ActiveCfg = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|ARM.Build.0 = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|ARM64.Build.0 = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|x64.ActiveCfg = Debug|x64
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|x64.Build.0 = Debug|x64
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|x86.ActiveCfg = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Debug|x86.Build.0 = Debug|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|Any CPU.Build.0 = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|ARM.ActiveCfg = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|ARM.Build.0 = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|ARM64.ActiveCfg = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|ARM64.Build.0 = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|x64.ActiveCfg = Release|x64
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|x64.Build.0 = Release|x64
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|x86.ActiveCfg = Release|Any CPU
{F6040CB8-83EE-47B9-8DD7-DF43CD555956}.Release|x86.Build.0 = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|ARM.Build.0 = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|ARM64.Build.0 = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|x64.ActiveCfg = Debug|x64
{66433384-A10C-44A5-B734-400990A569F0}.Debug|x64.Build.0 = Debug|x64
{66433384-A10C-44A5-B734-400990A569F0}.Debug|x86.ActiveCfg = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Debug|x86.Build.0 = Debug|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|Any CPU.Build.0 = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|ARM.ActiveCfg = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|ARM.Build.0 = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|ARM64.ActiveCfg = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|ARM64.Build.0 = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|x64.ActiveCfg = Release|x64
{66433384-A10C-44A5-B734-400990A569F0}.Release|x64.Build.0 = Release|x64
{66433384-A10C-44A5-B734-400990A569F0}.Release|x86.ActiveCfg = Release|Any CPU
{66433384-A10C-44A5-B734-400990A569F0}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -123,6 +123,9 @@
<Compile Include="SampleFlyout.xaml.cs">
<DependentUpon>SampleFlyout.xaml</DependentUpon>
</Compile>
<Compile Include="Test.xaml.cs">
<DependentUpon>Test.xaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
@@ -161,16 +164,20 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Test.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls.csproj">
<Project>{a970d11a-ad9f-4a3f-a509-16fa5f9ac779}</Project>
<Name>TheXamlGuy.NotificationFlyout.Uwp.UI.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj">
<Project>{a970d11a-ad9f-4a3f-a509-16fa5f9ac779}</Project>
<Name>TheXamlGuy.NotificationFlyout.Shared.UI</Name>
</ProjectReference>
<Reference Include="TheXamlGuy.NotificationFlyout.Shared.UI, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\src\TheXamlGuy.NotificationFlyout.Shared.UI\bin\x64\Release\uap10.0.19041\TheXamlGuy.NotificationFlyout.Shared.UI.dll</HintPath>
</Reference>
<Reference Include="TheXamlGuy.NotificationFlyout.Uwp.UI.Controls, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\src\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls\bin\x64\Release\uap10.0.19041\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls.dll</HintPath>
</Reference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
@@ -2,11 +2,32 @@
x:Class="NotificationFlyoutSample.SampleFlyout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:TheXamlGuy.NotificationFlyout.Uwp.UI.Controls">
<Grid Width="400" Height="600">
<Button
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="Hello World!" />
xmlns:controls="using:TheXamlGuy.NotificationFlyout.Uwp.UI.Controls"
VerticalContentAlignment="Top">
<controls:NotificationFlyout.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Click="OnCloseMenuFlyoutItemClick" Text="Close" />
</MenuFlyout>
</controls:NotificationFlyout.ContextFlyout>
<Grid Margin="24" VerticalAlignment="Top">
<StackPanel Background="Red">
<ToggleSwitch
Header="Is light dimissed enabled"
IsOn="True"
OffContent="False"
OnContent="True"
Toggled="ToggleSwitch_Toggled" />
<ComboBox Header="Placement" SelectionChanged="ComboBox_SelectionChanged">
<ComboBoxItem Content="Auto" />
<ComboBoxItem Content="FullRight" />
</ComboBox>
<Slider />
<TextBox />
<CalendarDatePicker />
<CalendarView />
<Button Click="Button_Click" Content="hello" />
<TimePicker />
</StackPanel>
</Grid>
</controls:NotificationFlyout>
@@ -1,4 +1,6 @@
using Windows.UI.Xaml;
using TheXamlGuy.NotificationFlyout.Uwp.UI.Controls;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace NotificationFlyoutSample
{
@@ -10,9 +12,42 @@ namespace NotificationFlyoutSample
}
private void OnCloseMenuFlyoutItemClick(object sender, RoutedEventArgs args)
{
{
var app = GetApplication();
app.Exit();
}
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
var toggleSwitch = sender as ToggleSwitch;
if (toggleSwitch.IsOn)
{
this.IsLightDismissEnabled = true;
}
else
{
this.IsLightDismissEnabled = false;
}
}
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var comboBox = sender as ComboBox;
if (comboBox.SelectedIndex == 0)
{
this.Placement = NotificationFlyoutPlacement.Auto;
}
else
{
this.Placement = NotificationFlyoutPlacement.FullRight;
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var app = GetApplication();
app.OpenAsWindow<Test>();
}
}
}
@@ -0,0 +1,25 @@
<UserControl
x:Class="NotificationFlyoutSample.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:NotificationFlyoutSample"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
d:DesignHeight="300"
d:DesignWidth="400"
mc:Ignorable="d">
<Grid>
<Button Click="TestButtonClick1" Content="Show TeachingTip" />
<muxc:TeachingTip x:Name="ToggleThemeTeachingTip1" ShouldConstrainToRootBounds="False">
<muxc:TeachingTip.Content>
<Border Width="500" Height="500">
<Slider />
</Border>
</muxc:TeachingTip.Content>
</muxc:TeachingTip>
</Grid>
</UserControl>
@@ -0,0 +1,33 @@
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 NotificationFlyoutSample
{
public sealed partial class Test : UserControl
{
public Test()
{
this.InitializeComponent();
}
private void TestButtonClick1(object sender, RoutedEventArgs e)
{
ToggleThemeTeachingTip1.XamlRoot = this.XamlRoot;
ToggleThemeTeachingTip1.IsOpen = true;
}
}
}
@@ -24,7 +24,7 @@ namespace TheXamlGuy.NotificationFlyout.Common.Helpers
GetAppBarPosition(ref appBarData);
state.Rect = appBarData.rect.ToRect();
state.Position = (TaskbarPosition)appBarData.uEdge;
state.Placement = (TaskbarPlacement)appBarData.uEdge;
return state;
}
@@ -1,7 +1,7 @@
namespace TheXamlGuy.NotificationFlyout.Common.Helpers
{
public enum TaskbarPosition
public enum TaskbarPlacement
{
Left = 0,
Top = 1,
@@ -4,7 +4,7 @@ namespace TheXamlGuy.NotificationFlyout.Common.Helpers
{
public struct TaskbarState
{
public TaskbarPosition Position;
public TaskbarPlacement Placement;
public Rect Rect;
public Screen Screen;
}
@@ -6,6 +6,10 @@ namespace TheXamlGuy.NotificationFlyout.Shared.UI
{
void Exit();
void OpenFlyout();
void CloseFlyout();
void OpenAsWindow<TUIElement>() where TUIElement : UIElement;
}
}
@@ -1,72 +1,70 @@
using System;
using System.Numerics;
using TheXamlGuy.NotificationFlyout.Shared.UI;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
[ContentProperty(Name = "Content")]
public class NotificationFlyout : DependencyObject
public class NotificationFlyout : ContentControl
{
public static readonly DependencyProperty FlyoutPresenterStyleProperty =
DependencyProperty.Register(nameof(FlyoutPresenterStyle),
typeof(Style), typeof(NotificationFlyout),
new PropertyMetadata(null));
public static readonly DependencyProperty IconSourceProperty =
DependencyProperty.Register(nameof(IconSource),
typeof(ImageSource), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static readonly DependencyProperty IsLightDismissEnabledProperty =
DependencyProperty.Register(nameof(IsLightDismissEnabled),
typeof(bool), typeof(NotificationFlyout),
new PropertyMetadata(true));
public static readonly DependencyProperty LightIconSourceProperty =
DependencyProperty.Register(nameof(LightIconSource),
DependencyProperty.Register(nameof(LightIconSource),
typeof(ImageSource), typeof(NotificationFlyout),
new PropertyMetadata(null));
public static readonly DependencyProperty RequestedThemeProperty =
DependencyProperty.Register(nameof(RequestedTheme),
typeof(ElementTheme), typeof(NotificationFlyout),
new PropertyMetadata(ElementTheme.Default));
public static readonly DependencyProperty PlacementProperty =
DependencyProperty.Register(nameof(Placement),
typeof(NotificationFlyoutPlacement), typeof(NotificationFlyout),
new PropertyMetadata(NotificationFlyoutPlacement.Auto, OnPlacementPropertyChanged));
public static DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content),
typeof(UIElement), typeof(NotificationFlyout),
new PropertyMetadata(null));
public static readonly DependencyProperty TemplateSettingsProperty =
DependencyProperty.Register(nameof(TemplateSettings),
typeof(NotificationFlyoutTemplateSettings), typeof(NotificationFlyout),
new PropertyMetadata(null));
public static DependencyProperty ContextMenuProperty =
DependencyProperty.Register(nameof(ContextMenu),
typeof(NotificationFlyoutContextMenu), typeof(NotificationFlyout),
new PropertyMetadata(null, OnContextMenuPropertyChanged));
private const double OffsetValue = 6;
private static INotificationFlyoutApplication _applicationInstance;
private Border _backgroundElement;
private UIElement _child;
private Border _container;
private Popup _popup;
public NotificationFlyout()
{
DefaultStyleKey = typeof(NotificationFlyout);
TemplateSettings = new NotificationFlyoutTemplateSettings();
}
public event EventHandler<object> Closed;
public event TypedEventHandler<NotificationFlyout, NotificationFlyoutClosingEventArgs> Closing;
public event EventHandler<object> Opened;
public event EventHandler<object> Opening;
internal event EventHandler ContextMenuChanged;
internal event EventHandler IconSourceChanged;
internal event EventHandler IconSourcePropertyChanged;
public UIElement Content
{
get => (UIElement)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
internal event EventHandler InteractedWith;
public NotificationFlyoutContextMenu ContextMenu
{
get => (NotificationFlyoutContextMenu)GetValue(ContextMenuProperty);
set => SetValue(ContextMenuProperty, value);
}
public Style FlyoutPresenterStyle
{
get => (Style)GetValue(FlyoutPresenterStyleProperty);
set => SetValue(FlyoutPresenterStyleProperty, value);
}
internal event EventHandler PlacementPropertyChanged;
public ImageSource IconSource
{
@@ -74,34 +72,188 @@ namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
set => SetValue(IconSourceProperty, value);
}
public bool IsLightDismissEnabled
{
get => (bool)GetValue(IsLightDismissEnabledProperty);
set => SetValue(IsLightDismissEnabledProperty, value);
}
public ImageSource LightIconSource
{
get => (ImageSource)GetValue(LightIconSourceProperty);
set => SetValue(LightIconSourceProperty, value);
}
public ElementTheme RequestedTheme
public NotificationFlyoutPlacement Placement
{
get => (ElementTheme)GetValue(RequestedThemeProperty);
set => SetValue(RequestedThemeProperty, value);
get => (NotificationFlyoutPlacement)GetValue(PlacementProperty);
set => SetValue(PlacementProperty, value);
}
public NotificationFlyoutTemplateSettings TemplateSettings
{
get => (NotificationFlyoutTemplateSettings)GetValue(TemplateSettingsProperty);
set => SetValue(TemplateSettingsProperty, value);
}
public static INotificationFlyoutApplication GetApplication() => _applicationInstance;
public void Close()
{
if (_popup == null)
{
PreparePopup();
}
_popup.IsOpen = false;
}
public void Open()
{
if (_popup == null)
{
PreparePopup();
}
if (!_popup.IsOpen)
{
_popup.Child = _child;
_popup.IsOpen = true;
}
}
internal static void SetApplication(INotificationFlyoutApplication application) => _applicationInstance = application;
internal void InvokeClosedEvent(object obj) => Closed?.Invoke(this, obj);
internal void InvokeClosingEvent(NotificationFlyoutClosingEventArgs eventArgs) => Closing?.Invoke(this, eventArgs);
internal void InvokeOpenedEvent(object obj) => Opened?.Invoke(this, obj);
internal void InvokeOpeningEvent(object obj) => Opening?.Invoke(this, obj);
private static void OnContextMenuPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
internal void Close(bool shouldRespectIsLightDismissEnbabled)
{
var sender = dependencyObject as NotificationFlyout;
sender?.OnContextMenuPropertyChanged();
if (!shouldRespectIsLightDismissEnbabled || IsLightDismissEnabled)
{
Close();
}
}
internal void SetPlacement(double horizontalOffset, double verticalOffset, double workingAreaHeight, double workingAreaWidth, NotificationFlyoutTaskbarPlacement flyoutTaskbarPlacement)
{
if (_popup == null)
{
PreparePopup();
}
VisualStateManager.GoToState(this, "DefaultPlacement", true);
_child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
var width = _child.DesiredSize.Width - 1;
var height = Placement == NotificationFlyoutPlacement.Auto ? _child.DesiredSize.Height : workingAreaHeight + 1;
var desiredHorizontalOffset = horizontalOffset;
var desiredVerticalOffset = verticalOffset;
var visualState = "";
switch (Placement)
{
case NotificationFlyoutPlacement.Auto:
visualState = $"{flyoutTaskbarPlacement}";
switch (flyoutTaskbarPlacement)
{
case NotificationFlyoutTaskbarPlacement.Left:
desiredHorizontalOffset -= OffsetValue;
desiredVerticalOffset -= height;
break;
case NotificationFlyoutTaskbarPlacement.Top:
desiredHorizontalOffset -= width + OffsetValue;
desiredVerticalOffset -= OffsetValue;
break;
case NotificationFlyoutTaskbarPlacement.Right:
desiredHorizontalOffset -= width + OffsetValue;
desiredVerticalOffset -= height;
break;
case NotificationFlyoutTaskbarPlacement.Bottom:
desiredHorizontalOffset -= width + OffsetValue;
desiredVerticalOffset -= height;
break;
}
break;
case NotificationFlyoutPlacement.FullRight:
visualState = $"{Placement}";
switch (flyoutTaskbarPlacement)
{
case NotificationFlyoutTaskbarPlacement.Left:
desiredHorizontalOffset += workingAreaWidth - width - OffsetValue;
desiredVerticalOffset = -OffsetValue;
break;
case NotificationFlyoutTaskbarPlacement.Top:
desiredHorizontalOffset = workingAreaWidth - width - OffsetValue;
desiredVerticalOffset += -OffsetValue;
break;
case NotificationFlyoutTaskbarPlacement.Right:
desiredHorizontalOffset -= width + OffsetValue;
desiredVerticalOffset = -OffsetValue;
break;
case NotificationFlyoutTaskbarPlacement.Bottom:
desiredHorizontalOffset -= width + OffsetValue;
desiredVerticalOffset = -OffsetValue;
break;
}
break;
}
TemplateSettings.SetValue(NotificationFlyoutTemplateSettings.HeightProperty, height);
TemplateSettings.SetValue(NotificationFlyoutTemplateSettings.WidthProperty, width);
TemplateSettings.SetValue(NotificationFlyoutTemplateSettings.NegativeHeightProperty, -height);
TemplateSettings.SetValue(NotificationFlyoutTemplateSettings.NegativeWidthProperty, -width);
_popup.SetValue(Popup.HorizontalOffsetProperty, desiredHorizontalOffset);
_popup.SetValue(Popup.VerticalOffsetProperty, desiredVerticalOffset);
VisualStateManager.GoToState(this, $"{visualState}Placement", true);
}
internal void ShowContextMenuAt(double x, double y)
{
if (ContextFlyout == null) return;
ContextFlyout.ShouldConstrainToRootBounds = false;
ContextFlyout.XamlRoot = XamlRoot;
ContextFlyout.ShowAt(_container);
ContextFlyout.ShowAt(_container, new FlyoutShowOptions
{
Position = new Point(x, y),
ShowMode = FlyoutShowMode.Standard
});
}
internal void UpdateTheme(bool isColorPrevalence) => VisualStateManager.GoToState(this, isColorPrevalence ? "ColorPrevalenceTheme" : "DefaultTheme", true);
protected override void OnApplyTemplate()
{
_container = GetTemplateChild("Container") as Border;
if (_container != null)
{
if (_child != null)
{
_child.PointerPressed += OnPointerPressed;
_child.GotFocus -= OnGotFocus;
}
_child = _container.Child;
_child.PointerPressed += OnPointerPressed;
_child.GotFocus += OnGotFocus;
_container.Child = null;
}
_backgroundElement = GetTemplateChild("BackgroundElement") as Border;
if (_backgroundElement != null)
{
_backgroundElement.Shadow = new ThemeShadow();
var currentTranslation = _backgroundElement.Translation;
var translation = new Vector3(currentTranslation.X, currentTranslation.Y, 32.0f);
_backgroundElement.Translation = translation;
}
}
private static void OnIconPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
@@ -110,8 +262,42 @@ namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
sender?.OnIconPropertyChanged();
}
private void OnContextMenuPropertyChanged() => ContextMenuChanged?.Invoke(this, EventArgs.Empty);
private static void OnPlacementPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
var sender = dependencyObject as NotificationFlyout;
sender?.OnPlacementPropertyChanged();
}
private void OnIconPropertyChanged() => IconSourceChanged?.Invoke(this, EventArgs.Empty);
private void OnGotFocus(object sender, RoutedEventArgs args) => InteractedWith?.Invoke(this, EventArgs.Empty);
private void OnIconPropertyChanged() => IconSourcePropertyChanged?.Invoke(this, EventArgs.Empty);
private void OnPlacementPropertyChanged() => PlacementPropertyChanged?.Invoke(this, EventArgs.Empty);
private void OnPointerPressed(object sender, PointerRoutedEventArgs args) => InteractedWith?.Invoke(this, EventArgs.Empty);
private void OnPopupClosed(object sender, object args) => Closed?.Invoke(this, args);
private void OnPopupOpened(object sender, object args) => Opened?.Invoke(this, args);
private void PreparePopup()
{
if (_popup != null)
{
_popup.Opened -= OnPopupOpened;
_popup.Closed -= OnPopupClosed;
}
_popup = new Popup
{
XamlRoot = XamlRoot,
ShouldConstrainToRootBounds = false,
HorizontalOffset = -OffsetValue,
VerticalOffset = -OffsetValue
};
_popup.Opened += OnPopupOpened;
_popup.Closed += OnPopupClosed;
}
}
}
@@ -0,0 +1,123 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:TheXamlGuy.NotificationFlyout.Uwp.UI.Controls">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<AcrylicBrush
x:Key="AcrylicBackgroundFillColorBrush"
BackgroundSource="HostBackdrop"
FallbackColor="#2C2C2C"
TintColor="#2C2C2C"
TintOpacity="0.8" />
<StaticResource x:Key="NotificationFlyoutPresenterBackgroundBrush" ResourceKey="AcrylicBackgroundFillColorBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<AcrylicBrush
x:Key="AcrylicBackgroundFillColorBrush"
BackgroundSource="HostBackdrop"
FallbackColor="#F9F9F9"
TintColor="#FCFCFC"
TintOpacity="0.8" />
<StaticResource x:Key="NotificationFlyoutPresenterBackgroundBrush" ResourceKey="AcrylicBackgroundFillColorBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<AcrylicBrush
x:Key="NotificationFlyoutPresenterBackgroundAccentBrush"
BackgroundSource="HostBackdrop"
FallbackColor="{ThemeResource SystemAccentColorDark1}"
TintColor="{ThemeResource SystemAccentColorDark1}"
TintOpacity="0.8" />
<Style TargetType="controls:NotificationFlyout">
<Setter Property="Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundBrush}" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyout">
<Border x:Name="Container">
<Grid x:Name="LayoutRoot" Margin="{TemplateBinding Margin}">
<Border
x:Name="BackgroundElement"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BackgroundSizing="OuterBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Border.Transitions>
<TransitionCollection>
<EntranceThemeTransition x:Name="EntranceThemeTransition" />
</TransitionCollection>
</Border.Transitions>
<Grid>
<ScrollViewer
x:Name="ScrollViewer"
AutomationProperties.AccessibilityView="Raw"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ContentControl
x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ScrollViewer>
</Grid>
</Border>
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PlacementStates">
<VisualState x:Name="DefaultPlacement" />
<VisualState x:Name="BottomPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.Height}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="TopPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeHeight}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="LeftPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.NegativeWidth}" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="RightPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.Width}" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="FullRightPlacement">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.Width}" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
<Setter Target="BackgroundElement.Height" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.Height, Mode=TwoWay}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ThemeStates">
<VisualState x:Name="DefaultTheme" />
<VisualState x:Name="ColorPrevalenceTheme">
<VisualState.Setters>
<Setter Target="BackgroundElement.Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundAccentBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -1,9 +0,0 @@
using System;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
public sealed class NotificationFlyoutClosingEventArgs : EventArgs
{
public bool Cancel { get; set; }
}
}
@@ -1,25 +0,0 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Markup;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
[ContentProperty(Name = "MenuItems")]
public class NotificationFlyoutContextMenu : DependencyObject
{
public static DependencyProperty MenuItemsProperty =
DependencyProperty.Register(nameof(MenuItems),
typeof(IList<MenuFlyoutItemBase>), typeof(NotificationFlyout),
new PropertyMetadata(null));
public NotificationFlyoutContextMenu() => MenuItems = new ObservableCollection<MenuFlyoutItemBase>();
public IList<MenuFlyoutItemBase> MenuItems
{
get => (IList<MenuFlyoutItemBase>)GetValue(MenuItemsProperty);
set => SetValue(MenuItemsProperty, value);
}
}
}
@@ -0,0 +1,10 @@
using Windows.UI.Xaml.Controls.Primitives;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
public enum NotificationFlyoutPlacement
{
Auto,
FullRight
}
}
@@ -0,0 +1,10 @@
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
internal enum NotificationFlyoutTaskbarPlacement
{
Left,
Top,
Right,
Bottom,
}
}
@@ -0,0 +1,50 @@
using Windows.UI.Xaml;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
public class NotificationFlyoutTemplateSettings : DependencyObject
{
public static readonly DependencyProperty HeightProperty =
DependencyProperty.Register(nameof(Height),
typeof(double), typeof(NotificationFlyoutTemplateSettings),
new PropertyMetadata(0d));
public static readonly DependencyProperty NegativeHeightProperty =
DependencyProperty.Register(nameof(NegativeHeight),
typeof(double), typeof(NotificationFlyoutTemplateSettings),
new PropertyMetadata(0d));
public static readonly DependencyProperty NegativeWidthProperty =
DependencyProperty.Register(nameof(NegativeWidth),
typeof(double), typeof(NotificationFlyoutTemplateSettings),
new PropertyMetadata(0d));
public static readonly DependencyProperty WidthProperty =
DependencyProperty.Register(nameof(Width),
typeof(double), typeof(NotificationFlyoutTemplateSettings),
new PropertyMetadata(0d));
public double Height
{
get => (double)GetValue(HeightProperty);
set => SetValue(HeightProperty, value);
}
public double NegativeHeight
{
get => (double)GetValue(NegativeHeightProperty);
set => SetValue(NegativeHeightProperty, value);
}
public double NegativeWidth
{
get => (double)GetValue(NegativeWidthProperty);
set => SetValue(NegativeWidthProperty, value);
}
public double Width
{
get => (double)GetValue(WidthProperty);
set => SetValue(WidthProperty, value);
}
}
}
@@ -1,100 +0,0 @@
using System.Collections.Specialized;
using System.Linq;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
internal class NotificationFlyoutContextMenuFlyoutHost : Control
{
private NotificationFlyout _flyout;
private MenuFlyout _menuFlyout;
private Grid _root;
public NotificationFlyoutContextMenuFlyoutHost() => DefaultStyleKey = typeof(NotificationFlyoutContextMenuFlyoutHost);
public void HideFlyout()
{
if (_menuFlyout == null) return;
_menuFlyout.Hide();
}
public void ShowFlyout()
{
if (_root == null) return;
if (_menuFlyout == null) return;
_menuFlyout.ShowAt(_root, new FlyoutShowOptions
{
Placement = FlyoutPlacementMode.BottomEdgeAlignedLeft,
ShowMode = FlyoutShowMode.TransientWithDismissOnPointerMoveAway
});
}
internal void SetOwningFlyout(NotificationFlyout flyout)
{
if (_flyout != null)
{
(_flyout.ContextMenu.MenuItems as INotifyCollectionChanged).CollectionChanged -= OnContextMenuItemsChanged;
}
_flyout = flyout;
var contextMenu = _flyout.ContextMenu;
if (contextMenu == null) return;
(contextMenu.MenuItems as INotifyCollectionChanged).CollectionChanged += OnContextMenuItemsChanged;
PrepareMenuItems();
}
protected override void OnApplyTemplate()
{
_root = GetTemplateChild("Root") as Grid;
_menuFlyout = GetTemplateChild("Flyout") as MenuFlyout;
PrepareMenuItems();
}
private void OnContextMenuItemsChanged(object sender, NotifyCollectionChangedEventArgs args)
{
if (_flyout == null) return;
var contextMenu = _flyout.ContextMenu;
if (contextMenu == null) return;
var addedItems = args.NewItems.Cast<MenuFlyoutItemBase>().ToList();
var removedItems = args.NewItems.Cast<MenuFlyoutItemBase>().ToList();
if (removedItems != null)
{
foreach (var item in removedItems)
{
_menuFlyout.Items.Remove(item);
}
}
foreach (var item in addedItems)
{
_menuFlyout.Items.Add(item);
}
}
private void PrepareMenuItems()
{
if (_menuFlyout == null) return;
if (_flyout == null) return;
var contextMenu = _flyout.ContextMenu;
if (contextMenu == null) return;
_menuFlyout.Items.Clear();
var items = contextMenu.MenuItems;
foreach (var item in items)
{
_menuFlyout.Items.Add(item);
}
}
}
}
@@ -1,18 +0,0 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:TheXamlGuy.NotificationFlyout.Uwp.UI.Controls">
<Style TargetType="controls:NotificationFlyoutContextMenuFlyoutHost">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutContextMenuFlyoutHost">
<Grid x:Name="Root">
<FlyoutBase.AttachedFlyout>
<MenuFlyout x:Name="Flyout" />
</FlyoutBase.AttachedFlyout>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -1,134 +0,0 @@
using System.Numerics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
internal class NotificationFlyoutHost : Control
{
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content),
typeof(UIElement), typeof(NotificationFlyoutHost),
new PropertyMetadata(null));
public static readonly DependencyProperty FlyoutPresenterStyleProperty =
DependencyProperty.Register(nameof(FlyoutPresenterStyle),
typeof(Style), typeof(NotificationFlyoutHost),
new PropertyMetadata(null));
private Flyout _flyout;
private NotificationFlyout _notificationFlyout;
private NotificationFlyoutPresenter _notificationFlyoutPresenter;
private Grid _root;
public NotificationFlyoutHost() => DefaultStyleKey = typeof(NotificationFlyoutHost);
public UIElement Content
{
get => (UIElement)GetValue(ContentProperty);
set => SetValue(ContentProperty, value);
}
public Style FlyoutPresenterStyle
{
get => (Style)GetValue(FlyoutPresenterStyleProperty);
set => SetValue(FlyoutPresenterStyleProperty, value);
}
public void HideFlyout()
{
if (_root == null) return;
FlyoutBase flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.Hide();
}
public void SetFlyoutPlacement(string placement)
{
if (_notificationFlyoutPresenter == null) return;
_notificationFlyoutPresenter.UpdatePlacementVisualState(placement);
}
public void SetOwningFlyout(NotificationFlyout flyout)
{
_notificationFlyout = flyout;
BindingOperations.SetBinding(this, ContentProperty,
new Binding
{
Source = _notificationFlyout,
Path =
new PropertyPath(nameof(Content)),
Mode = BindingMode.TwoWay
});
BindingOperations.SetBinding(this, RequestedThemeProperty,
new Binding
{
Source = _notificationFlyout,
Path = new PropertyPath(nameof(RequestedTheme)),
Mode = BindingMode.TwoWay
});
BindingOperations.SetBinding(this, FlyoutPresenterStyleProperty,
new Binding
{
Source = _notificationFlyout,
Path = new PropertyPath(nameof(FlyoutPresenterStyle)),
Mode = BindingMode.TwoWay
});
}
public void ShowFlyout(FlyoutPlacementMode placementMode)
{
if (_root == null) return;
var flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.ShowAt(_root, new FlyoutShowOptions
{
Placement = placementMode,
ShowMode = FlyoutShowMode.Transient,
});
}
public void UpdateTheme(bool isColorPrevalence)
{
if (_notificationFlyoutPresenter == null) return;
_notificationFlyoutPresenter.UpdateThemeVisualState(isColorPrevalence);
}
protected override void OnApplyTemplate()
{
_notificationFlyoutPresenter = GetTemplateChild("NotificationFlyoutPresenter") as NotificationFlyoutPresenter;
if (_notificationFlyoutPresenter != null)
{
_notificationFlyoutPresenter.ApplyTemplate();
}
_flyout = GetTemplateChild("Flyout") as Flyout;
if (_flyout != null)
{
_flyout.Closing -= OnFlyoutClosing;
_flyout.Closed -= OnFlyoutClosed;
_flyout.Opening -= OnFlyoutOpening;
_flyout.Opened -= OnFlyoutOpened;
_flyout.Closing += OnFlyoutClosing;
_flyout.Closed += OnFlyoutClosed;
_flyout.Opening += OnFlyoutOpening;
_flyout.Opened += OnFlyoutOpened;
}
_root = GetTemplateChild("Root") as Grid;
}
private void OnFlyoutClosed(object sender, object args) => _notificationFlyout?.InvokeClosedEvent(args);
private void OnFlyoutClosing(FlyoutBase sender, FlyoutBaseClosingEventArgs args) => _notificationFlyout?.InvokeClosingEvent(new NotificationFlyoutClosingEventArgs());
private void OnFlyoutOpened(object sender, object args) => _notificationFlyout?.InvokeOpenedEvent(args);
private void OnFlyoutOpening(object sender, object args) => _notificationFlyout?.InvokeOpeningEvent(args);
}
}
@@ -1,100 +0,0 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:TheXamlGuy.NotificationFlyout.Uwp.UI.Controls">
<Style TargetType="controls:NotificationFlyoutHost">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutHost">
<Grid x:Name="Root">
<Grid.Resources>
<Style x:Key="DefaultFlyoutPresenterStyle" TargetType="FlyoutPresenter">
<Setter Property="IsDefaultShadowEnabled" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="FlyoutPresenter">
<ContentPresenter
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style
x:Key="TopFlyoutPresenterStyle"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Margin" Value="0,-7,0,0" />
</Style>
<Style
x:Key="BottomFlyoutPresenterStyle"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Margin" Value="0,7,0,0" />
</Style>
<Style
x:Key="LeftFlyoutPresenterStyle"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Margin" Value="-7,0,0,0" />
</Style>
<Style
x:Key="RightFlyoutPresenterStyle"
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="Margin" Value="7,0,0,0" />
</Style>
</Grid.Resources>
<FlyoutBase.AttachedFlyout>
<Flyout
x:Name="Flyout"
AreOpenCloseAnimationsEnabled="False"
FlyoutPresenterStyle="{StaticResource BottomFlyoutPresenterStyle}"
ShouldConstrainToRootBounds="False">
<controls:NotificationFlyoutPresenter
x:Name="NotificationFlyoutPresenter"
Content="{TemplateBinding Content}"
Style="{TemplateBinding FlyoutPresenterStyle}" />
</Flyout>
</FlyoutBase.AttachedFlyout>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PlacementStates">
<VisualState x:Name="Bottom">
<VisualState.Setters>
<Setter Target="Flyout.FlyoutPresenterStyle" Value="{StaticResource BottomFlyoutPresenterStyle}" />
<!--<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="80" />-->
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Top">
<VisualState.Setters>
<Setter Target="Flyout.FlyoutPresenterStyle" Value="{StaticResource TopFlyoutPresenterStyle}" />
<!--<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="-80" />-->
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Left">
<VisualState.Setters>
<Setter Target="Flyout.FlyoutPresenterStyle" Value="{StaticResource LeftFlyoutPresenterStyle}" />
<!--<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="-80" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />-->
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Right">
<VisualState.Setters>
<Setter Target="Flyout.FlyoutPresenterStyle" Value="{StaticResource RightFlyoutPresenterStyle}" />
<!--<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="80" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />-->
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -1,28 +0,0 @@
using System.Numerics;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
namespace TheXamlGuy.NotificationFlyout.Uwp.UI.Controls
{
public class NotificationFlyoutPresenter : ContentControl
{
public NotificationFlyoutPresenter() => DefaultStyleKey = typeof(NotificationFlyoutPresenter);
protected override void OnApplyTemplate()
{
if (GetTemplateChild("Root") is Grid contentRoot)
{
contentRoot.Shadow = new ThemeShadow();
var currentTranslation = contentRoot.Translation;
var translation = new Vector3(currentTranslation.X, currentTranslation.Y, 16.0f);
contentRoot.Translation = translation;
}
}
internal void UpdatePlacementVisualState(string placement) => VisualStateManager.GoToState(this, placement, true);
internal void UpdateThemeVisualState(bool isColorPrevalence) => VisualStateManager.GoToState(this, isColorPrevalence ? "ColorPrevalenceTheme" : "DefaultTheme", true);
}
}
@@ -1,112 +0,0 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:TheXamlGuy.NotificationFlyout.Uwp.UI.Controls">
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Default">
<AcrylicBrush
x:Key="AcrylicBackgroundFillColorBrush"
BackgroundSource="HostBackdrop"
FallbackColor="#2C2C2C"
TintColor="#2C2C2C"
TintOpacity="0.8" />
<StaticResource x:Key="NotificationFlyoutPresenterBackgroundBrush" ResourceKey="AcrylicBackgroundFillColorBrush" />
</ResourceDictionary>
<ResourceDictionary x:Key="Light">
<AcrylicBrush
x:Key="AcrylicBackgroundFillColorBrush"
BackgroundSource="HostBackdrop"
FallbackColor="#F9F9F9"
TintColor="#FCFCFC"
TintOpacity="0.8" />
<StaticResource x:Key="NotificationFlyoutPresenterBackgroundBrush" ResourceKey="AcrylicBackgroundFillColorBrush" />
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
<AcrylicBrush
x:Key="NotificationFlyoutPresenterBackgroundAccentBrush"
BackgroundSource="HostBackdrop"
FallbackColor="{ThemeResource SystemAccentColorDark1}"
TintColor="{ThemeResource SystemAccentColorDark1}"
TintOpacity="0.8" />
<Style TargetType="controls:NotificationFlyoutPresenter">
<Setter Property="Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundBrush}" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutPresenter">
<Grid
x:Name="Root"
Padding="{TemplateBinding Padding}"
Background="{TemplateBinding Background}"
BackgroundSizing="OuterBorderEdge"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}">
<Grid.Transitions>
<TransitionCollection>
<EntranceThemeTransition
x:Name="EntranceThemeTransition"
FromHorizontalOffset="0"
FromVerticalOffset="0" />
</TransitionCollection>
</Grid.Transitions>
<ScrollViewer
x:Name="ScrollViewer"
AutomationProperties.AccessibilityView="Raw"
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ContentControl
x:Name="ContentPresenter"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ScrollViewer>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="PlacementStates">
<VisualState x:Name="Bottom">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="80" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Top">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="0" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="-80" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Left">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="-80" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="Right">
<VisualState.Setters>
<Setter Target="EntranceThemeTransition.FromHorizontalOffset" Value="80" />
<Setter Target="EntranceThemeTransition.FromVerticalOffset" Value="0" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="ThemeStates">
<VisualState x:Name="DefaultTheme" />
<VisualState x:Name="ColorPrevalenceTheme">
<VisualState.Setters>
<Setter Target="Root.Background" Value="{ThemeResource NotificationFlyoutPresenterBackgroundAccentBrush}" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -14,15 +14,7 @@
</PropertyGroup>
<ItemGroup>
<Page Include="NotificationFlyoutHost\NotificationFlyoutContextMenuFlyoutHost.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="NotificationFlyoutHost\NotificationFlyoutHost.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.xaml">
<Page Include="NotificationFlyout\NotificationFlyout.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -1,7 +1,5 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///TheXamlGuy.NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutHost/NotificationFlyoutHost.xaml" />
<ResourceDictionary Source="ms-appx:///TheXamlGuy.NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml" />
<ResourceDictionary Source="ms-appx:///TheXamlGuy.NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutHost/NotificationFlyoutContextMenuFlyoutHost.xaml" />
<ResourceDictionary Source="ms-appx:///TheXamlGuy.NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyout.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
@@ -1,7 +1,19 @@
using TheXamlGuy.NotificationFlyout.Common.Helpers;
using System.Windows;
using System.Windows.Markup;
using System;
using Windows.UI.Xaml.Controls;
using TheXamlGuy.NotificationFlyout.Uwp.UI.Controls;
using TheXamlGuy.NotificationFlyout.Wpf.UI.Extensions;
using System.Windows.Media.Imaging;
using TheXamlGuy.NotificationFlyout.Common.Extensions;
using Microsoft.Windows.Sdk;
using TheXamlGuy.NotificationFlyout.Shared.UI;
using System.Windows.Media;
using System.Threading.Tasks;
using Microsoft.Win32;
using System.Windows.Threading;
using System.Threading;
namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
{
@@ -13,37 +25,61 @@ namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
typeof(Uwp.UI.Controls.NotificationFlyout), typeof(NotificationFlyoutApplication),
new PropertyMetadata(null, OnFlyoutPropertyChanged));
private static NotificationFlyoutApplication _application;
private NotificationFlyoutXamlHost _notificationFlyoutXamlHost;
private const string ShellTrayHandleName = "Shell_TrayWnd";
private readonly NotificationIconHelper _notificationIconHelper;
private readonly SystemPersonalisationHelper _systemPersonalisationHelper;
private readonly TaskbarHelper _taskbarHelper;
private bool _isDpiChanging;
private TransparentXamlHost<ContentControl> _notificationFlyoutXamlHost;
public NotificationFlyoutApplication()
{
_application = this;
Uwp.UI.Controls.NotificationFlyout.SetApplication(this);
_notificationIconHelper = NotificationIconHelper.Create();
_notificationIconHelper.IconInvoked += OnIconInvoked;
_taskbarHelper = TaskbarHelper.Create();
_taskbarHelper.TaskbarChanged += OnTaskbarChanged;
_systemPersonalisationHelper = SystemPersonalisationHelper.Current;
_systemPersonalisationHelper.ThemeChanged += OnThemeChanged;
WndProcListener.Current.Start();
PrepareFlyoutHost();
WndProcListener.Current.Start();
}
public static INotificationFlyoutApplication Current => _application;
public Uwp.UI.Controls.NotificationFlyout Flyout
{
get => (Uwp.UI.Controls.NotificationFlyout)GetValue(FlyoutProperty);
set => SetValue(FlyoutProperty, value);
}
public void Exit() => _notificationFlyoutXamlHost.Close();
public void CloseFlyout(bool shouldRespectIsLightDismissEnbabled)
{
if (Flyout == null) return;
Flyout.Close(shouldRespectIsLightDismissEnbabled);
}
public void HideFlyout() => _notificationFlyoutXamlHost.HideFlyout();
public void CloseFlyout() => CloseFlyout(false);
public void Exit() => _notificationFlyoutXamlHost.Close();
public void OpenAsWindow<TUIElement>() where TUIElement : Windows.UI.Xaml.UIElement
{
var window = new XamlHost<TUIElement>();
window.Hidden();
window.Show();
}
public void ShowFlyout() => _notificationFlyoutXamlHost.ShowFlyout();
public void OpenFlyout()
{
if (Flyout == null) return;
_notificationFlyoutXamlHost.Activate();
Flyout.Open();
UpdateFlyoutPlacement();
}
private static void OnFlyoutPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
@@ -51,12 +87,188 @@ namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
sender?.OnFlyoutPropertyChanged();
}
private void OnFlyoutPropertyChanged() => _notificationFlyoutXamlHost.SetOwningFlyout(Flyout);
private void OnFlyoutIconSourcePropertyChanged(object sender, EventArgs args) => UpdateIcons();
private void OnFlyoutInteractedWith(object sender, EventArgs args) => _notificationFlyoutXamlHost.Activate();
private void OnFlyoutPlacementPropertyChanged(object sender, EventArgs args) => UpdateFlyoutPlacement();
private void OnFlyoutPropertyChanged() => PrepareFlyout();
private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args)
{
if (args.PointerButton == PointerButton.Left)
{
OpenFlyout();
}
if (args.PointerButton == PointerButton.Right)
{
ShowContextMenu();
}
}
private void OnNotificationFlyoutXamlHostClosed(object sender, EventArgs args) => _notificationIconHelper?.Dispose();
private void OnNotificationFlyoutXamlHostDeactivated(object sender, EventArgs args) => CloseFlyout(true);
private async void OnNotificationFlyoutXamlHostDpiChanged(object sender, DpiChangedEventArgs args)
{
if (_isDpiChanging)
return;
_isDpiChanging = true;
await Application.Current.Dispatcher.Invoke(async () =>
{
_notificationFlyoutXamlHost.Visibility = Visibility.Visible;
await Dispatcher.BeginInvoke(new Action(() =>
{
VisualTreeHelper.SetRootDpi(_notificationFlyoutXamlHost, args.OldDpi);
}), DispatcherPriority.ContextIdle, null);
await Dispatcher.BeginInvoke(new Action(() =>
{
VisualTreeHelper.SetRootDpi(_notificationFlyoutXamlHost, args.NewDpi);
}), DispatcherPriority.ContextIdle, null);
await Dispatcher.BeginInvoke(new Action(() =>
{
_notificationFlyoutXamlHost.Visibility = Visibility.Hidden;
_isDpiChanging = false;
}), DispatcherPriority.ContextIdle, null);
});
UpdateIcons();
}
private void OnTaskbarChanged(object sender, EventArgs args) => UpdateFlyoutPlacement();
private void OnThemeChanged(object sender, SystemPersonalisationChangedEventArgs args)
{
UpdateIcons();
UpdateTheme();
}
private void PrepareFlyout()
{
if (Flyout == null) return;
Flyout.IconSourcePropertyChanged += OnFlyoutIconSourcePropertyChanged;
Flyout.PlacementPropertyChanged += OnFlyoutPlacementPropertyChanged;
Flyout.InteractedWith += OnFlyoutInteractedWith;
var content = _notificationFlyoutXamlHost.GetHostContent();
if (content != null)
{
content.Content = Flyout;
}
UpdateIcons();
}
private void PrepareFlyoutHost()
{
_notificationFlyoutXamlHost = new NotificationFlyoutXamlHost();
_notificationFlyoutXamlHost = new TransparentXamlHost<ContentControl>();
_notificationFlyoutXamlHost.DpiChanged += OnNotificationFlyoutXamlHostDpiChanged;
_notificationFlyoutXamlHost.Closed += OnNotificationFlyoutXamlHostClosed;
_notificationFlyoutXamlHost.Deactivated += OnNotificationFlyoutXamlHostDeactivated;
var taskbarState = _taskbarHelper.GetCurrentState();
_notificationFlyoutXamlHost.Left = taskbarState.Screen.WorkingArea.Left;
_notificationFlyoutXamlHost.Top = taskbarState.Screen.WorkingArea.Top;
_notificationFlyoutXamlHost.Show();
}
private void ShowContextMenu()
{
var dpiX = _notificationFlyoutXamlHost.DpiX();
var dpiY = _notificationFlyoutXamlHost.DpiY();
PInvoke.GetPhysicalCursorPos(out POINT point);
Flyout.ShowContextMenuAt(point.x / dpiX, point.y / dpiY);
}
private void UpdateFlyoutPlacement()
{
if (Flyout == null) return;
var dpiX = _notificationFlyoutXamlHost.DpiX();
var dpiY = _notificationFlyoutXamlHost.DpiY();
var taskbarState = _taskbarHelper.GetCurrentState();
_notificationFlyoutXamlHost.Left = taskbarState.Screen.Bounds.Left / dpiX; ;
_notificationFlyoutXamlHost.Top = 0;
double horizontalOffset;
double verticalOffset;
var workingAreaHeight = taskbarState.Screen.WorkingArea.Height / dpiX;
var workingAreaWidth = taskbarState.Screen.WorkingArea.Width / dpiY;
NotificationFlyoutTaskbarPlacement flyoutTaskBarPlacement;
switch (taskbarState.Placement)
{
case TaskbarPlacement.Left:
flyoutTaskBarPlacement = NotificationFlyoutTaskbarPlacement.Left;
verticalOffset = taskbarState.Screen.WorkingArea.Height / dpiX;
horizontalOffset = taskbarState.Rect.Width / dpiY;
break;
case TaskbarPlacement.Top:
flyoutTaskBarPlacement = NotificationFlyoutTaskbarPlacement.Top;
verticalOffset = taskbarState.Rect.Height / dpiX;
horizontalOffset = (_notificationFlyoutXamlHost.FlowDirection == FlowDirection.RightToLeft ? 0 : taskbarState.Screen.WorkingArea.Width) / dpiY;
break;
case TaskbarPlacement.Right:
flyoutTaskBarPlacement = NotificationFlyoutTaskbarPlacement.Right;
verticalOffset = taskbarState.Screen.WorkingArea.Height / dpiX;
horizontalOffset = taskbarState.Screen.WorkingArea.Width / dpiY;
break;
case TaskbarPlacement.Bottom:
flyoutTaskBarPlacement = NotificationFlyoutTaskbarPlacement.Bottom;
verticalOffset = taskbarState.Screen.WorkingArea.Height / dpiX;
horizontalOffset = (_notificationFlyoutXamlHost.FlowDirection == FlowDirection.RightToLeft ? 0 : taskbarState.Screen.WorkingArea.Width) / dpiY;
break;
default:
throw new ArgumentOutOfRangeException();
}
Flyout.SetPlacement(horizontalOffset, verticalOffset, workingAreaHeight, workingAreaWidth, flyoutTaskBarPlacement);
}
private async void UpdateIcons()
{
if (Flyout == null) return;
var shellTrayHandle = WindowHelper.GetHandle(ShellTrayHandleName);
if (shellTrayHandle == null) return;
var dpi = WindowHelper.GetDpi(shellTrayHandle);
var desiredIconSource = _systemPersonalisationHelper.Theme == SystemTheme.Dark ? Flyout.IconSource : Flyout.LightIconSource;
if (desiredIconSource == null)
{
var fallbackIconSource = new BitmapImage(new Uri($"pack://application:,,,/{GetType().Namespace};component/Assets/notification-icon-{(_systemPersonalisationHelper.Theme == SystemTheme.Dark ? "default" : "light")}.ico"));
using var icon = fallbackIconSource.ConvertToIcon(dpi);
_notificationIconHelper.SetIcon(icon.Handle);
}
else
{
using var icon = await desiredIconSource.ConvertToIconAsync(dpi);
_notificationIconHelper.SetIcon(icon.Handle);
}
}
private void UpdateTheme()
{
if (Flyout == null) return;
Flyout.UpdateTheme(_systemPersonalisationHelper.IsColorPrevalence);
}
}
}
@@ -1,44 +0,0 @@
using TheXamlGuy.NotificationFlyout.Uwp.UI.Controls;
using TheXamlGuy.NotificationFlyout.Common.Helpers;
using TheXamlGuy.NotificationFlyout.Wpf.UI.Extensions;
using System;
namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
{
internal class NotificationFlyoutContextMenuXamlHost : TransparentXamlHost<NotificationFlyoutContextMenuFlyoutHost>
{
public NotificationFlyoutContextMenuXamlHost() => Topmost = true;
internal void SetOwningFlyout(Uwp.UI.Controls.NotificationFlyout flyout)
{
var content = GetHostContent();
if (content != null)
{
content.SetOwningFlyout(flyout);
}
}
internal void ShowContextMenuFlyout()
{
var position = CursorHelper.GetPhysicalCursorPos();
this.SetWindowPosition(position.y, position.x, WindowSize, WindowSize);
var flyoutHost = GetHostContent();
if (flyoutHost != null)
{
flyoutHost.ShowFlyout();
}
Activate();
}
protected override void OnDeactivated(EventArgs args)
{
var flyoutHost = GetHostContent();
if (flyoutHost != null)
{
flyoutHost.HideFlyout();
}
}
}
}
@@ -1,248 +0,0 @@
using TheXamlGuy.NotificationFlyout.Common.Extensions;
using TheXamlGuy.NotificationFlyout.Common.Helpers;
using TheXamlGuy.NotificationFlyout.Uwp.UI.Controls;
using TheXamlGuy.NotificationFlyout.Wpf.UI.Extensions;
using System;
using System.Windows;
using Windows.UI.Xaml.Controls.Primitives;
using System.Windows.Media.Imaging;
namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
{
internal class NotificationFlyoutXamlHost : TransparentXamlHost<NotificationFlyoutHost>
{
private const string ShellTrayHandleName = "Shell_TrayWnd";
private NotificationFlyoutContextMenuXamlHost _contextMenuXamlHost;
private Uwp.UI.Controls.NotificationFlyout _flyout;
private NotificationIconHelper _notificationIconHelper;
private SystemPersonalisationHelper _systemPersonalisationHelper;
private TaskbarHelper _taskbarHelper;
internal void HideFlyout()
{
var flyoutHost = GetHostContent();
if (flyoutHost != null)
{
flyoutHost.HideFlyout();
}
}
internal void SetOwningFlyout(Uwp.UI.Controls.NotificationFlyout flyout)
{
if (_flyout != null)
{
_flyout.IconSourceChanged -= OnIconSourceChanged;
_flyout.ContextMenuChanged -= OnContextMenuChanged;
}
_flyout = flyout;
_flyout.IconSourceChanged += OnIconSourceChanged;
_flyout.ContextMenuChanged += OnContextMenuChanged;
var content = GetHostContent();
if (content != null)
{
content.SetOwningFlyout(_flyout);
}
UpdateIcons();
PrepareContextMenu();
}
internal void ShowFlyout()
{
var content = GetHostContent();
if (content != null)
{
var taskbarState = _taskbarHelper.GetCurrentState();
var flyoutPlacement = taskbarState.Position switch
{
TaskbarPosition.Left => FlyoutPlacementMode.Right,
TaskbarPosition.Top => FlyoutPlacementMode.Bottom,
TaskbarPosition.Right => FlyoutPlacementMode.Left,
TaskbarPosition.Bottom => FlyoutPlacementMode.Top,
_ => throw new ArgumentOutOfRangeException(),
};
Activate();
content.ShowFlyout(flyoutPlacement);
}
}
protected override void OnClosed(EventArgs args)
{
_notificationIconHelper.Dispose();
if (_contextMenuXamlHost == null) return;
_contextMenuXamlHost.Close();
}
protected override void OnContentLoaded()
{
PrepareNotificationIcon();
PrepareTaskbar();
UpdateWindow();
UpdateTheme();
}
protected override void OnDeactivated(EventArgs args) => HideFlyout();
private void OnContextMenuChanged(object sender, EventArgs args) => PrepareContextMenu();
private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args)
{
if (args.PointerButton == PointerButton.Left)
{
ShowFlyout();
}
if (args.PointerButton == PointerButton.Right)
{
ShowContextMenuFlyout();
}
}
private void OnIconSourceChanged(object sender, EventArgs args) => UpdateIcons();
private void OnTaskbarChanged(object sender, EventArgs args) => UpdateWindow();
private void OnThemeChanged(object sender, SystemPersonalisationChangedEventArgs args)
{
UpdateTheme();
UpdateIcons();
}
private void PrepareContextMenu()
{
if (_contextMenuXamlHost != null)
{
_contextMenuXamlHost.Close();
_contextMenuXamlHost = null;
}
var contextMenu = _flyout.ContextMenu;
if (contextMenu == null) return;
if (_contextMenuXamlHost == null)
{
_contextMenuXamlHost = new NotificationFlyoutContextMenuXamlHost();
_contextMenuXamlHost.Show();
}
_contextMenuXamlHost.SetOwningFlyout(_flyout);
}
private void PrepareNotificationIcon()
{
_notificationIconHelper = NotificationIconHelper.Create();
_notificationIconHelper.IconInvoked += OnIconInvoked;
_systemPersonalisationHelper = SystemPersonalisationHelper.Current;
_systemPersonalisationHelper.ThemeChanged += OnThemeChanged;
UpdateIcons();
}
private void PrepareTaskbar()
{
_taskbarHelper = TaskbarHelper.Create();
_taskbarHelper.TaskbarChanged += OnTaskbarChanged;
}
private void ShowContextMenuFlyout()
{
if (_contextMenuXamlHost == null) return;
_contextMenuXamlHost.ShowContextMenuFlyout();
}
private async void UpdateIcons()
{
if (!IsLoaded) return;
if (_flyout == null) return;
var shellTrayHandle = WindowHelper.GetHandle(ShellTrayHandleName);
if (shellTrayHandle == null) return;
var dpi = WindowHelper.GetDpi(shellTrayHandle);
var desiredIconSource = _systemPersonalisationHelper.Theme == SystemTheme.Dark ? _flyout.IconSource : _flyout.LightIconSource;
if (desiredIconSource == null)
{
var fallbackIconSource = new BitmapImage(new Uri($"pack://application:,,,/{GetType().Namespace};component/Assets/notification-icon-{(_systemPersonalisationHelper.Theme == SystemTheme.Dark ? "default" : "light")}.ico"));
using var icon = fallbackIconSource.ConvertToIcon(dpi);
_notificationIconHelper.SetIcon(icon.Handle);
}
else
{
using var icon = await desiredIconSource.ConvertToIconAsync(dpi);
_notificationIconHelper.SetIcon(icon.Handle);
}
}
private void UpdateTheme()
{
var content = GetHostContent();
if (content != null)
{
content.UpdateTheme(_systemPersonalisationHelper.IsColorPrevalence);
}
}
private void UpdateWindow()
{
if (!IsLoaded) return;
var flyoutHost = GetHostContent();
if (flyoutHost == null) return;
var taskbarState = _taskbarHelper.GetCurrentState();
Left = taskbarState.Screen.WorkingArea.Left;
Top = taskbarState.Screen.WorkingArea.Top;
var windowWidth = WindowSize * this.DpiX();
var windowHeight = WindowSize * this.DpiY();
double top, left, height, width;
var taskbarRect = taskbarState.Rect;
switch (taskbarState.Position)
{
case TaskbarPosition.Left:
top = taskbarRect.Bottom - windowHeight;
left = taskbarRect.Right;
height = windowHeight;
width = windowWidth;
break;
case TaskbarPosition.Top:
top = taskbarRect.Bottom;
left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth;
height = windowHeight;
width = windowWidth;
break;
case TaskbarPosition.Right:
top = taskbarRect.Bottom - windowHeight;
left = taskbarRect.Left - windowWidth;
height = windowHeight;
width = windowWidth;
break;
case TaskbarPosition.Bottom:
top = taskbarRect.Top - windowHeight;
left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth;
height = windowHeight;
width = windowWidth;
break;
default:
throw new ArgumentOutOfRangeException();
}
this.SetWindowPosition(top, left, height, width);
flyoutHost.SetFlyoutPlacement(taskbarState.Position.ToString());
}
}
}
@@ -22,6 +22,8 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj" />
<ProjectReference Include="..\TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj" />
<ProjectReference Include="..\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls\TheXamlGuy.NotificationFlyout.Uwp.UI.Controls.csproj" />
<ProjectReference Include="..\TheXamlGuy.NotificationFlyout.Wpf.UI\TheXamlGuy.NotificationFlyout.Wpf.UI.csproj" />
</ItemGroup>
@@ -1,37 +1,33 @@
using Microsoft.Toolkit.Wpf.UI.XamlHost;
using TheXamlGuy.NotificationFlyout.Wpf.UI.Extensions;
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
{
internal class TransparentXamlHost<TXamlContent> : XamlHost<TXamlContent> where TXamlContent : Windows.UI.Xaml.UIElement
{
internal const double WindowSize = 5;
internal const double WindowSize = 10;
public TransparentXamlHost()
{
Loaded += OnLoaded;
PrepareDefaultWindow();
}
public TransparentXamlHost() => PrepareDefaultWindow();
protected override WindowsXamlHost OnPreparingXamlHost(WindowsXamlHost xamlHost)
{
xamlHost.Height = 0;
xamlHost.Width = 0;
return base.OnPreparingXamlHost(xamlHost);
}
Dispatcher.BeginInvoke(new Action(() =>
{
Hide();
}), DispatcherPriority.ContextIdle, null);
private void OnLoaded(object sender, RoutedEventArgs args)
{
this.Hidden();
return base.OnPreparingXamlHost(xamlHost);
}
private void PrepareDefaultWindow()
{
ShowInTaskbar = false;
ShowActivated = false;
WindowStyle = WindowStyle.None;
ResizeMode = ResizeMode.NoResize;
AllowsTransparency = true;
@@ -6,13 +6,11 @@ namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
{
internal class XamlHost<TXamlContent> : Window where TXamlContent : Windows.UI.Xaml.UIElement
{
protected new bool IsLoaded;
private WindowsXamlHost _xamlHost;
public XamlHost()
{
PrepareWindowsXamlHost();
ContentRendered += OnContentRendered;
}
internal TXamlContent GetHostContent()
@@ -21,11 +19,6 @@ namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
return _xamlHost.GetUwpInternalObject() as TXamlContent;
}
protected virtual void OnContentLoaded()
{
}
protected virtual WindowsXamlHost OnPreparingXamlHost(WindowsXamlHost xamlHost)
{
xamlHost.InitialTypeName = typeof(TXamlContent).FullName;
@@ -35,12 +28,6 @@ namespace TheXamlGuy.NotificationFlyout.Wpf.UI.Controls
return xamlHost;
}
private void OnContentRendered(object sender, EventArgs args)
{
IsLoaded = true;
OnContentLoaded();
}
private void PrepareWindowsXamlHost()
{
_xamlHost = new WindowsXamlHost();
@@ -20,7 +20,6 @@
<ItemGroup>
<ProjectReference Include="..\TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj" />
<ProjectReference Include="..\TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj" />
</ItemGroup>
</Project>
+2 -2
View File
@@ -14,9 +14,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyo
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Wpf.UI.Controls", "TheXamlGuy.NotificationFlyout.Wpf.UI.Controls\TheXamlGuy.NotificationFlyout.Wpf.UI.Controls.csproj", "{3205F101-E5F3-4B57-B0BB-33693F906B77}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheXamlGuy.NotificationFlyout.Shared.UI", "TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj", "{341F9830-BB2F-4A2F-A81A-3DBAF307B4EF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Shared.UI", "TheXamlGuy.NotificationFlyout.Shared.UI\TheXamlGuy.NotificationFlyout.Shared.UI.csproj", "{341F9830-BB2F-4A2F-A81A-3DBAF307B4EF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheXamlGuy.NotificationFlyout.Common", "TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj", "{4F05A3D6-DBBC-4921-97BA-6843925CD74B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TheXamlGuy.NotificationFlyout.Common", "TheXamlGuy.NotificationFlyout.Common\TheXamlGuy.NotificationFlyout.Common.csproj", "{4F05A3D6-DBBC-4921-97BA-6843925CD74B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution