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

This commit is contained in:
Daniel Clark
2021-02-06 17:38:39 +00:00
parent 3de9ceee0d
commit 3fdfcfaf21
26 changed files with 260 additions and 282 deletions
@@ -55,12 +55,12 @@
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion> <TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<DefaultLanguage>en-US</DefaultLanguage> <DefaultLanguage>en-US</DefaultLanguage>
<AppxPackageSigningEnabled>false</AppxPackageSigningEnabled> <AppxPackageSigningEnabled>false</AppxPackageSigningEnabled>
<EntryPointProjectUniqueName>..\NotificationFlyout.Tray\NotificationFlyout.Tray.csproj</EntryPointProjectUniqueName>
<GenerateAppInstallerFile>False</GenerateAppInstallerFile> <GenerateAppInstallerFile>False</GenerateAppInstallerFile>
<AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision> <AppxAutoIncrementPackageRevision>True</AppxAutoIncrementPackageRevision>
<GenerateTestArtifacts>True</GenerateTestArtifacts> <GenerateTestArtifacts>True</GenerateTestArtifacts>
<AppxBundlePlatforms>neutral</AppxBundlePlatforms> <AppxBundlePlatforms>neutral</AppxBundlePlatforms>
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks> <HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
<EntryPointProjectUniqueName>..\NotificationFlyout.Tray\NotificationFlyout.Sample.Wpf.csproj</EntryPointProjectUniqueName>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<AppxBundle>Always</AppxBundle> <AppxBundle>Always</AppxBundle>
@@ -111,7 +111,7 @@
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.19041.8" PrivateAssets="all" /> <PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.19041.8" PrivateAssets="all" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\NotificationFlyout.Tray\NotificationFlyout.Tray.csproj"> <ProjectReference Include="..\NotificationFlyout.Tray\NotificationFlyout.Sample.Wpf.csproj">
<SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties> <SkipGetTargetFrameworkProperties>True</SkipGetTargetFrameworkProperties>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
@@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace NotificationFlyout.Sample
{
public sealed partial class MyUserControl1 : UserControl
{
public MyUserControl1()
{
this.InitializeComponent();
}
}
}
@@ -120,8 +120,8 @@
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MyUserControl1.xaml.cs"> <Compile Include="NotificationFlyoutPresenter.xaml.cs">
<DependentUpon>MyUserControl1.xaml</DependentUpon> <DependentUpon>NotificationFlyoutPresenter.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\NotificationFlyout.Sample.rd.xml" /> <EmbeddedResource Include="Properties\NotificationFlyout.Sample.rd.xml" />
@@ -135,11 +135,17 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Include="MyUserControl1.xaml"> <Page Include="NotificationFlyoutPresenter.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj">
<Project>{9987b132-e42c-401a-9ad5-e62529faca40}</Project>
<Name>NotificationFlyout.Uwp.UI.Controls</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' "> <PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion> <VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup> </PropertyGroup>
@@ -1,7 +1,9 @@
<UserControl <controls:NotificationFlyoutPresenter
x:Class="NotificationFlyout.Sample.MyUserControl1" x:Class="NotificationFlyout.Sample.NotificationFlyoutPresenter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls"
CornerRadius="4">
<Grid> <Grid>
<ListBox <ListBox
Width="300" Width="300"
@@ -15,4 +17,4 @@
<ListBoxItem Content="Item 6" /> <ListBoxItem Content="Item 6" />
</ListBox> </ListBox>
</Grid> </Grid>
</UserControl> </controls:NotificationFlyoutPresenter>
@@ -0,0 +1,10 @@
namespace NotificationFlyout.Sample
{
public sealed partial class NotificationFlyoutPresenter
{
public NotificationFlyoutPresenter()
{
InitializeComponent();
}
}
}
+4 -4
View File
@@ -1,4 +1,4 @@
<Application x:Class="NotificationFlyout.Tray.App" <Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Class="NotificationFlyout.Sample.Wpf.App"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
</Application> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />
+1 -1
View File
@@ -1,6 +1,6 @@
using System.Windows; using System.Windows;
namespace NotificationFlyout.Tray namespace NotificationFlyout.Sample.Wpf
{ {
public partial class App : Application public partial class App : Application
{ {
@@ -6,8 +6,9 @@
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<AssetTargetFallback>uap10.0.19041</AssetTargetFallback> <AssetTargetFallback>uap10.0.19041</AssetTargetFallback>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
<StartupObject>NotificationFlyout.Tray.Program</StartupObject> <StartupObject>NotificationFlyout.Sample.Wpf.Program</StartupObject>
<LangVersion>9.0</LangVersion> <LangVersion>9.0</LangVersion>
<AssemblyName>NotificationFlyout.Sample.Wpf</AssemblyName>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
+4 -5
View File
@@ -1,7 +1,6 @@
using NotificationFlyout.Tray.Views; using System;
using System;
namespace NotificationFlyout.Tray namespace NotificationFlyout.Sample.Wpf
{ {
public class Program public class Program
{ {
@@ -9,9 +8,9 @@ namespace NotificationFlyout.Tray
public static void Main() public static void Main()
{ {
using (new XamlHost.App()) using (new XamlHost.App())
{ {
var app = new App(); var app = new App();
new Shell(); new SampleNotificationFlyout();
app.Run(); app.Run();
} }
} }
@@ -1,10 +1,2 @@
using System.Windows; using System.Windows;
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
@@ -1,10 +1,8 @@
<NotificationFlyout <NotificationFlyout
x:Class="NotificationFlyout.Tray.Views.Shell" x:Class="NotificationFlyout.Sample.Wpf.SampleNotificationFlyout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sample="clr-namespace:NotificationFlyout.Sample;assembly=NotificationFlyout.Sample"> xmlns:sample="clr-namespace:NotificationFlyout.Sample;assembly=NotificationFlyout.Sample"
<NotificationFlyout.Icon> IconSource="/Assets/Icon.ico">
<NotificationFlyoutIcon IconSource="/Assets/Icon.ico" /> <sample:NotificationFlyoutPresenter />
</NotificationFlyout.Icon>
<sample:MyUserControl1 />
</NotificationFlyout> </NotificationFlyout>
@@ -0,0 +1,10 @@
namespace NotificationFlyout.Sample.Wpf
{
public partial class SampleNotificationFlyout
{
public SampleNotificationFlyout()
{
InitializeComponent();
}
}
}
@@ -1,10 +0,0 @@
namespace NotificationFlyout.Tray.Views
{
public partial class Shell
{
public Shell()
{
InitializeComponent();
}
}
}
@@ -120,8 +120,9 @@
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="NotificationFlyoutHost\NotificationFlyoutHost.cs" />
<Compile Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.cs" /> <Compile Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.cs" />
<Compile Include="NotificationFlyoutPresenter\NotificationFlyoutPresenterTemplateSettings.cs" /> <Compile Include="NotificationFlyoutHost\NotificationFlyoutHostTemplateSettings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\NotificationFlyout.Uwp.UI.Controls.rd.xml" /> <EmbeddedResource Include="Properties\NotificationFlyout.Uwp.UI.Controls.rd.xml" />
</ItemGroup> </ItemGroup>
@@ -134,10 +135,14 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Page Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.xaml"> <Page Include="NotificationFlyoutHost\NotificationFlyoutHost.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\Generic.xaml"> <Page Include="Themes\Generic.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -0,0 +1,72 @@
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace NotificationFlyout.Uwp.UI.Controls
{
public class NotificationFlyoutHost : Control
{
public static readonly DependencyProperty FlyoutPresenterProperty =
DependencyProperty.Register(nameof(FlyoutPresenter),
typeof(NotificationFlyoutPresenter), typeof(NotificationFlyoutHost),
new PropertyMetadata(null));
public static readonly DependencyProperty TemplateSettingsProperty =
DependencyProperty.Register(nameof(TemplateSettings),
typeof(NotificationFlyoutHostTemplateSettings), typeof(NotificationFlyoutHost),
new PropertyMetadata(null));
private readonly NotificationFlyoutHostTemplateSettings _templateSettings;
private Grid _root;
public NotificationFlyoutHost()
{
DefaultStyleKey = typeof(NotificationFlyoutHost);
_templateSettings = new NotificationFlyoutHostTemplateSettings();
SetValue(TemplateSettingsProperty, _templateSettings);
}
public NotificationFlyoutPresenter FlyoutPresenter
{
get => (NotificationFlyoutPresenter)GetValue(FlyoutPresenterProperty);
set => SetValue(FlyoutPresenterProperty, value);
}
public NotificationFlyoutHostTemplateSettings TemplateSettings
{
get => (NotificationFlyoutHostTemplateSettings)GetValue(TemplateSettingsProperty);
set => SetValue(TemplateSettingsProperty, value);
}
public void HideFlyout()
{
if (_root == null) return;
FlyoutBase flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.Hide();
}
public void SetOffset(double verticalOffset, double horizontalOffset)
{
if (_templateSettings == null) return;
_templateSettings.FromVerticalOffset = verticalOffset;
_templateSettings.FromHorizontalOffset = horizontalOffset;
}
public void ShowFlyout(FlyoutPlacementMode placementMode)
{
if (_root == null) return;
var flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.ShowAt(_root, new FlyoutShowOptions
{
Placement = placementMode,
ShowMode = FlyoutShowMode.Standard
});
}
protected override void OnApplyTemplate()
{
_root = GetTemplateChild("Root") as Grid;
}
}
}
@@ -0,0 +1,29 @@
<ResourceDictionary
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">
<Style TargetType="controls:NotificationFlyoutHost">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutHost">
<Grid x:Name="Root">
<FlyoutBase.AttachedFlyout>
<Flyout AreOpenCloseAnimationsEnabled="False" ShouldConstrainToRootBounds="False">
<Flyout.FlyoutPresenterStyle>
<Style TargetType="FlyoutPresenter">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="IsDefaultShadowEnabled" Value="False" />
<Setter Property="Padding" Value="0" />
<Setter Property="Margin" Value="0" />
</Style>
</Flyout.FlyoutPresenterStyle>
<ContentControl Content="{TemplateBinding FlyoutPresenter}" />
</Flyout>
</FlyoutBase.AttachedFlyout>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -2,16 +2,16 @@
namespace NotificationFlyout.Uwp.UI.Controls namespace NotificationFlyout.Uwp.UI.Controls
{ {
public class NotificationFlyoutPresenterTemplateSettings : DependencyObject public class NotificationFlyoutHostTemplateSettings : DependencyObject
{ {
public static readonly DependencyProperty FromHorizontalOffsetProperty = public static readonly DependencyProperty FromHorizontalOffsetProperty =
DependencyProperty.Register(nameof(FromHorizontalOffset), DependencyProperty.Register(nameof(FromHorizontalOffset),
typeof(double), typeof(NotificationFlyoutPresenterTemplateSettings), typeof(double), typeof(NotificationFlyoutHostTemplateSettings),
new PropertyMetadata(0d)); new PropertyMetadata(0d));
public static readonly DependencyProperty FromVerticalOffsetProperty = public static readonly DependencyProperty FromVerticalOffsetProperty =
DependencyProperty.Register(nameof(FromVerticalOffset), DependencyProperty.Register(nameof(FromVerticalOffset),
typeof(double), typeof(NotificationFlyoutPresenterTemplateSettings), typeof(double), typeof(NotificationFlyoutHostTemplateSettings),
new PropertyMetadata(0d)); new PropertyMetadata(0d));
public double FromHorizontalOffset public double FromHorizontalOffset
@@ -1,71 +1,12 @@
using Windows.UI.Popups; using Windows.UI.Xaml.Controls;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace NotificationFlyout.Uwp.UI.Controls namespace NotificationFlyout.Uwp.UI.Controls
{ {
public class NotificationFlyoutPresenter : ContentControl public class NotificationFlyoutPresenter : ContentControl
{ {
public static readonly DependencyProperty TemplateSettingsProperty =
DependencyProperty.Register(nameof(TemplateSettings),
typeof(NotificationFlyoutPresenterTemplateSettings), typeof(NotificationFlyoutPresenter),
new PropertyMetadata(null));
private Grid _root;
private NotificationFlyoutPresenterTemplateSettings _templateSettings;
public NotificationFlyoutPresenter() public NotificationFlyoutPresenter()
{ {
DefaultStyleKey = typeof(NotificationFlyoutPresenter); DefaultStyleKey = typeof(NotificationFlyoutPresenter);
_templateSettings = new NotificationFlyoutPresenterTemplateSettings();
SetValue(TemplateSettingsProperty, _templateSettings);
UISettings uiSettings = new UISettings();
uiSettings.ColorValuesChanged += UiSettings_ColorValuesChanged;
}
private void UiSettings_ColorValuesChanged(UISettings sender, object args)
{
MessageDialog d = new MessageDialog("", "");
}
public NotificationFlyoutPresenterTemplateSettings TemplateSettings
{
get => (NotificationFlyoutPresenterTemplateSettings)GetValue(TemplateSettingsProperty);
set => SetValue(TemplateSettingsProperty, value);
}
public void SetOffset(double verticalOffset, double horizontalOffset)
{
if (_templateSettings == null) return;
_templateSettings.FromVerticalOffset = verticalOffset;
_templateSettings.FromHorizontalOffset = horizontalOffset;
}
public void HideFlyout()
{
if (_root == null) return;
FlyoutBase flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.Hide();
}
public void ShowFlyout(FlyoutPlacementMode placementMode)
{
if (_root == null) return;
var flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.ShowAt(_root, new FlyoutShowOptions
{
Placement = placementMode,
ShowMode = FlyoutShowMode.Standard
});
}
protected override void OnApplyTemplate()
{
_root = GetTemplateChild("Root") as Grid;
} }
} }
} }
@@ -7,50 +7,35 @@
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutPresenter"> <ControlTemplate TargetType="controls:NotificationFlyoutPresenter">
<Grid x:Name="Root"> <Border
<FlyoutBase.AttachedFlyout> Padding="{TemplateBinding Padding}"
<Flyout AreOpenCloseAnimationsEnabled="False" ShouldConstrainToRootBounds="False"> Background="{TemplateBinding Background}"
<Flyout.FlyoutPresenterStyle> BackgroundSizing="OuterBorderEdge"
<Style TargetType="FlyoutPresenter"> BorderBrush="{TemplateBinding BorderBrush}"
<Setter Property="BorderThickness" Value="0" /> BorderThickness="{TemplateBinding BorderThickness}"
<Setter Property="Background" Value="Transparent" /> CornerRadius="{TemplateBinding CornerRadius}">
<Setter Property="IsDefaultShadowEnabled" Value="False" /> <Border.Transitions>
<Setter Property="Padding" Value="0" /> <TransitionCollection>
<Setter Property="Margin" Value="0" /> <EntranceThemeTransition FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.FromHorizontalOffset, Mode=TwoWay}" FromVerticalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.FromVerticalOffset, Mode=TwoWay}" />
</Style> </TransitionCollection>
</Flyout.FlyoutPresenterStyle> </Border.Transitions>
<Border <ScrollViewer
Padding="{TemplateBinding Padding}" x:Name="ScrollViewer"
Background="{TemplateBinding Background}" AutomationProperties.AccessibilityView="Raw"
BackgroundSizing="OuterBorderEdge" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
BorderBrush="{TemplateBinding BorderBrush}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
BorderThickness="{TemplateBinding BorderThickness}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
CornerRadius="{TemplateBinding CornerRadius}"> VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
<Border.Transitions> ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<TransitionCollection> <ContentPresenter
<EntranceThemeTransition FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.FromHorizontalOffset, Mode=TwoWay}" FromVerticalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.FromVerticalOffset, Mode=TwoWay}" /> Margin="{TemplateBinding Padding}"
</TransitionCollection> HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
</Border.Transitions> VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
<ScrollViewer Content="{TemplateBinding Content}"
x:Name="ScrollViewer" ContentTemplate="{TemplateBinding ContentTemplate}"
AutomationProperties.AccessibilityView="Raw" ContentTransitions="{TemplateBinding ContentTransitions}" />
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" </ScrollViewer>
HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" </Border>
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
ZoomMode="{TemplateBinding ScrollViewer.ZoomMode}">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ScrollViewer>
</Border>
</Flyout>
</FlyoutBase.AttachedFlyout>
</Grid>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
@@ -1,9 +1,6 @@
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("NotificationFlyout.Uwp.UI.Controls")] [assembly: AssemblyTitle("NotificationFlyout.Uwp.UI.Controls")]
[assembly: AssemblyDescription("")] [assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
@@ -12,17 +9,6 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")] [assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
@@ -1,6 +1,6 @@
<ResourceDictionary <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutHost/NotificationFlyoutHost.xaml" />
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml" /> <ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyoutPresenter/NotificationFlyoutPresenter.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
@@ -1,26 +1,33 @@
using NotificationFlyout.Wpf.UI.Extensions; using NotificationFlyout.Uwp.UI.Controls;
using NotificationFlyout.Wpf.UI.Extensions;
using NotificationFlyout.Wpf.UI.Helpers; using NotificationFlyout.Wpf.UI.Helpers;
using System.Windows; using System.Windows;
using System.Windows.Markup; using System.Windows.Markup;
using System.Windows.Media;
namespace NotificationFlyout.Wpf.UI.Controls namespace NotificationFlyout.Wpf.UI.Controls
{ {
[ContentProperty(nameof(Content))] [ContentProperty(nameof(FlyoutPresenter))]
public class NotificationFlyout : DependencyObject public class NotificationFlyout : DependencyObject
{ {
public static readonly DependencyProperty IconSourceProperty =
DependencyProperty.Register(nameof(IconSource),
typeof(ImageSource), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static readonly DependencyProperty LightIconSourceProperty =
DependencyProperty.Register(nameof(LightIconSource),
typeof(ImageSource), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static DependencyProperty FlyoutPresenterProperty =
DependencyProperty.Register(nameof(FlyoutPresenter),
typeof(NotificationFlyoutPresenter), typeof(NotificationFlyout),
new PropertyMetadata(null, OnFlyoutPresenterPropertyChanged));
private const string ShellTrayHandleName = "Shell_TrayWnd"; private const string ShellTrayHandleName = "Shell_TrayWnd";
public static readonly DependencyProperty IconProperty = private readonly NotificationFlyoutXamlHost _xamlHost;
DependencyProperty.Register(nameof(Icon),
typeof(NotificationFlyoutIcon), typeof(NotificationFlyout),
new PropertyMetadata(null, OnIconPropertyChanged));
public static DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content),
typeof(Windows.UI.Xaml.UIElement), typeof(NotificationFlyout),
new PropertyMetadata(null, OnContentPropertyChanged));
private NotificationFlyoutXamlHost _xamlHost;
public NotificationFlyout() public NotificationFlyout()
{ {
@@ -28,16 +35,22 @@ namespace NotificationFlyout.Wpf.UI.Controls
_xamlHost.Show(); _xamlHost.Show();
} }
public Windows.UI.Xaml.UIElement Content public NotificationFlyoutPresenter FlyoutPresenter
{ {
get => (Windows.UI.Xaml.UIElement)GetValue(ContentProperty); get => (NotificationFlyoutPresenter)GetValue(FlyoutPresenterProperty);
set => SetValue(ContentProperty, value); set => SetValue(FlyoutPresenterProperty, value);
} }
public NotificationFlyoutIcon Icon public ImageSource IconSource
{ {
get => (NotificationFlyoutIcon)GetValue(IconProperty); get => (ImageSource)GetValue(IconSourceProperty);
set => SetValue(IconProperty, value); set => SetValue(IconSourceProperty, value);
}
public ImageSource LightIconSource
{
get => (ImageSource)GetValue(LightIconSourceProperty);
set => SetValue(LightIconSourceProperty, value);
} }
public void HideFlyout() public void HideFlyout()
@@ -50,10 +63,10 @@ namespace NotificationFlyout.Wpf.UI.Controls
_xamlHost.ShowFlyout(); _xamlHost.ShowFlyout();
} }
private static void OnContentPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs) private static void OnFlyoutPresenterPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{ {
var sender = dependencyObject as NotificationFlyout; var sender = dependencyObject as NotificationFlyout;
sender?.OnContentPropertyChanged(); sender?.OnFlyoutPresenterPropertyChanged();
} }
private static void OnIconPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args) private static void OnIconPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
@@ -62,9 +75,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
sender?.OnIconPropertyChanged(); sender?.OnIconPropertyChanged();
} }
private void OnContentPropertyChanged() private void OnFlyoutPresenterPropertyChanged()
{ {
_xamlHost.SetFlyoutContent(Content); _xamlHost.SetFlyoutPresenter(FlyoutPresenter);
} }
private void OnIconPropertyChanged() private void OnIconPropertyChanged()
@@ -74,7 +87,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
var dpi = WindowHelper.GetDpi(shellTrayHandle); var dpi = WindowHelper.GetDpi(shellTrayHandle);
var iconSource = SystemSettingsHelper.DefaultSystemTheme == SystemTheme.Dark ? Icon.IconSource : Icon.LightIconSource; var iconSource = SystemSettingsHelper.DefaultSystemTheme == SystemTheme.Dark ? IconSource : LightIconSource;
using var icon = iconSource.ConvertToIcon(dpi); using var icon = iconSource.ConvertToIcon(dpi);
_xamlHost.SetNotificationIcon(icon.Handle); _xamlHost.SetNotificationIcon(icon.Handle);
@@ -1,28 +0,0 @@
using System.Windows;
using System.Windows.Media;
namespace NotificationFlyout.Wpf.UI.Controls
{
public class NotificationFlyoutIcon : DependencyObject
{
public static readonly DependencyProperty IconSourceProperty =
DependencyProperty.Register(nameof(IconSource),
typeof(ImageSource), typeof(NotificationFlyout));
public static readonly DependencyProperty LightIconSourceProperty =
DependencyProperty.Register(nameof(LightIconSource),
typeof(ImageSource), typeof(NotificationFlyout));
public ImageSource IconSource
{
get => (ImageSource)GetValue(IconSourceProperty);
set => SetValue(IconSourceProperty, value);
}
public ImageSource LightIconSource
{
get => (ImageSource)GetValue(LightIconSourceProperty);
set => SetValue(LightIconSourceProperty, value);
}
}
}
@@ -12,10 +12,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
internal class NotificationFlyoutXamlHost : Window internal class NotificationFlyoutXamlHost : Window
{ {
private const double MaximumOffset = 80; private const double MaximumOffset = 80;
private WindowsXamlHost _host;
private NotificationIconHelper _notificationIconHelper; private NotificationIconHelper _notificationIconHelper;
private TaskbarHelper _taskbarHelper; private TaskbarHelper _taskbarHelper;
private WindowsXamlHost _xamlHost;
public NotificationFlyoutXamlHost() public NotificationFlyoutXamlHost()
{ {
@@ -25,21 +24,21 @@ namespace NotificationFlyout.Wpf.UI.Controls
Loaded += OnLoaded; Loaded += OnLoaded;
} }
public void SetFlyoutContent(Windows.UI.Xaml.UIElement content) public void SetFlyoutPresenter(NotificationFlyoutPresenter flyoutPresenter)
{ {
var flyoutPresenter = GetNotificationFlyoutPresenter(); var flyoutHost = GetFlyoutHost();
if (flyoutPresenter != null) if (flyoutHost != null)
{ {
flyoutPresenter.Content = content; flyoutHost.FlyoutPresenter = flyoutPresenter;
} }
} }
internal void HideFlyout() internal void HideFlyout()
{ {
var flyoutContentControl = GetNotificationFlyoutPresenter(); var flyoutHost = GetFlyoutHost();
if (flyoutContentControl != null) if (flyoutHost != null)
{ {
flyoutContentControl.HideFlyout(); flyoutHost.HideFlyout();
} }
} }
@@ -47,10 +46,11 @@ namespace NotificationFlyout.Wpf.UI.Controls
{ {
_notificationIconHelper.SetIcon(handle); _notificationIconHelper.SetIcon(handle);
} }
internal void ShowFlyout() internal void ShowFlyout()
{ {
var flyoutPresenter = GetNotificationFlyoutPresenter(); var flyoutHost = GetFlyoutHost();
if (flyoutPresenter != null) if (flyoutHost != null)
{ {
var taskbarState = _taskbarHelper.GetCurrentState(); var taskbarState = _taskbarHelper.GetCurrentState();
var flyoutPlacement = taskbarState.Position switch var flyoutPlacement = taskbarState.Position switch
@@ -63,15 +63,16 @@ namespace NotificationFlyout.Wpf.UI.Controls
}; };
Activate(); Activate();
flyoutPresenter.ShowFlyout(flyoutPlacement); flyoutHost.ShowFlyout(flyoutPlacement);
} }
} }
private NotificationFlyoutPresenter GetNotificationFlyoutPresenter() private NotificationFlyoutHost GetFlyoutHost()
{ {
if (_host == null) return null; if (_xamlHost == null) return null;
return _host.GetUwpInternalObject() as NotificationFlyoutPresenter; return _xamlHost.GetUwpInternalObject() as NotificationFlyoutHost;
} }
private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args) private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args)
{ {
ShowFlyout(); ShowFlyout();
@@ -120,21 +121,21 @@ namespace NotificationFlyout.Wpf.UI.Controls
private void PrepareWindowsXamlHost() private void PrepareWindowsXamlHost()
{ {
_host = new WindowsXamlHost _xamlHost = new WindowsXamlHost
{ {
InitialTypeName = typeof(NotificationFlyoutPresenter).FullName InitialTypeName = typeof(NotificationFlyoutHost).FullName
}; };
_host.Height = 0; _xamlHost.Height = 0;
_host.Width = 0; _xamlHost.Width = 0;
Content = _host; Content = _xamlHost;
} }
private void UpdateWindow() private void UpdateWindow()
{ {
var flyoutPresenter = GetNotificationFlyoutPresenter(); var flyoutHost = GetFlyoutHost();
if (flyoutPresenter == null) return; if (flyoutHost == null) return;
var taskbarState = _taskbarHelper.GetCurrentState(); var taskbarState = _taskbarHelper.GetCurrentState();
@@ -187,7 +188,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
} }
this.SetWindowPosition(top, left, height, width); this.SetWindowPosition(top, left, height, width);
flyoutPresenter.SetOffset(verticalOffset, horizontalOffset); flyoutHost.SetOffset(verticalOffset, horizontalOffset);
} }
} }
} }
@@ -1,10 +1,3 @@
using System.Windows; using System.Windows;
[assembly: ThemeInfo( [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
+1 -1
View File
@@ -7,7 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Foundati
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.XamlHost", "NotificationFlyout.XamlHost\NotificationFlyout.XamlHost.csproj", "{95D6E127-BC04-4591-ACFF-FB35BBB64884}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.XamlHost", "NotificationFlyout.XamlHost\NotificationFlyout.XamlHost.csproj", "{95D6E127-BC04-4591-ACFF-FB35BBB64884}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Tray", "NotificationFlyout.Tray\NotificationFlyout.Tray.csproj", "{B5B09576-6447-4146-B544-FB6000587D8B}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Sample.Wpf", "NotificationFlyout.Tray\NotificationFlyout.Sample.Wpf.csproj", "{B5B09576-6447-4146-B544-FB6000587D8B}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI.Controls", "NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj", "{0A782234-DC9F-4C4A-8820-FC640B03D233}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Wpf.UI.Controls", "NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj", "{0A782234-DC9F-4C4A-8820-FC640B03D233}"
EndProject EndProject