[WIP] Add context menu support

This commit is contained in:
Daniel Clark
2021-02-10 22:44:19 +00:00
parent 72983bef6a
commit 91b4f94e3f
29 changed files with 391 additions and 107 deletions
@@ -20,6 +20,7 @@
<ProjectReference Include="..\..\src\NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj" /> <ProjectReference Include="..\..\src\NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj" />
<ProjectReference Include="..\..\src\NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj" /> <ProjectReference Include="..\..\src\NotificationFlyout.Wpf.UI.Controls\NotificationFlyout.Wpf.UI.Controls.csproj" />
<ProjectReference Include="..\..\src\NotificationFlyout.Wpf.UI\NotificationFlyout.Wpf.UI.csproj" /> <ProjectReference Include="..\..\src\NotificationFlyout.Wpf.UI\NotificationFlyout.Wpf.UI.csproj" />
<ProjectReference Include="..\NotificationFlyout.Shared.UI\NotificationFlyout.Shared.UI.csproj" />
<ProjectReference Include="..\NotificationFlyoutSample\NotificationFlyoutSample.csproj" /> <ProjectReference Include="..\NotificationFlyoutSample\NotificationFlyoutSample.csproj" />
</ItemGroup> </ItemGroup>
+22
View File
@@ -22,6 +22,8 @@ Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "NotificationFlyoutSample.Pa
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI", "..\src\NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj", "{AFCE4980-A641-4BBB-A745-F0D4E54A0D86}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI", "..\src\NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj", "{AFCE4980-A641-4BBB-A745-F0D4E54A0D86}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.Shared.UI", "NotificationFlyout.Shared.UI\NotificationFlyout.Shared.UI.csproj", "{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -193,6 +195,26 @@ Global
{AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x64.Build.0 = Release|x64 {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x64.Build.0 = Release|x64
{AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x86.ActiveCfg = Release|Any CPU {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x86.ActiveCfg = Release|Any CPU
{AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x86.Build.0 = Release|Any CPU {AFCE4980-A641-4BBB-A745-F0D4E54A0D86}.Release|x86.Build.0 = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|ARM.Build.0 = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|ARM64.Build.0 = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|x64.ActiveCfg = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|x64.Build.0 = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|x86.ActiveCfg = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Debug|x86.Build.0 = Debug|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|Any CPU.Build.0 = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|ARM.ActiveCfg = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|ARM.Build.0 = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|ARM64.ActiveCfg = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|ARM64.Build.0 = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|x64.ActiveCfg = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|x64.Build.0 = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|x86.ActiveCfg = Release|Any CPU
{6D11191A-6A61-4A93-BEBB-EC34FE9FA403}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -1,4 +1,5 @@
using System; using NotificationFlyout.Wpf.UI.Controls;
using System;
namespace NotificationFlyoutSample.Host namespace NotificationFlyoutSample.Host
{ {
@@ -10,7 +11,10 @@ namespace NotificationFlyoutSample.Host
using (new NotificationFlyoutSample.App()) using (new NotificationFlyoutSample.App())
{ {
var app = new App(); var app = new App();
new SampleNotificationFlyout(); new NotificationFlyoutApplication
{
Flyout = new Shell()
};
app.Run(); app.Run();
} }
} }
@@ -1,9 +0,0 @@
<NotificationFlyout
x:Class="NotificationFlyoutSample.Host.SampleNotificationFlyout"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uwp="clr-namespace:NotificationFlyoutSample;assembly=NotificationFlyoutSample"
IconSource="/Assets/Icon.ico"
LightIconSource="/Assets/Icon-Light.ico">
<uwp:Shell />
</NotificationFlyout>
@@ -1,10 +0,0 @@
namespace NotificationFlyoutSample.Host
{
public partial class SampleNotificationFlyout
{
public SampleNotificationFlyout()
{
InitializeComponent();
}
}
}
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.30914.41 VisualStudioVersion = 16.0.30914.41
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyoutSample.Host", "NotificationFlyoutSample.Host\NotificationFlyoutSample.Host.csproj", "{D13742AD-DB71-4269-B3AF-7CA8C4E51A19}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyoutSample.Host", "NotificationFlyoutSample.Host\NotificationFlyoutSample.Host.csproj", "{D13742AD-DB71-4269-B3AF-7CA8C4E51A19}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyoutSample", "NotificationFlyoutSample\NotificationFlyoutSample.csproj", "{2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyoutSample", "NotificationFlyoutSample\NotificationFlyoutSample.csproj", "{2057ADE0-C61E-45EE-BB7E-A469FE4D4C41}"
EndProject EndProject
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

@@ -130,6 +130,8 @@
</AppxManifest> </AppxManifest>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Assets\Icon-Light.ico" />
<Content Include="Assets\Icon.ico" />
<Content Include="Properties\Default.rd.xml" /> <Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" /> <Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" /> <Content Include="Assets\SplashScreen.scale-200.png" />
@@ -1,16 +1,83 @@
<UserControl <controls:NotificationFlyout
x:Class="NotificationFlyoutSample.Shell" x:Class="NotificationFlyoutSample.Shell"
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:winui="using:Microsoft.UI.Xaml.Controls"> xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls"
<StackPanel xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
Width="330" IconSource="/Assets/Icon.ico"
Height="500" LightIconSource="/Assets/Icon-Light.ico">
Margin="24"> <StackPanel Margin="24">
<ComboBox
x:Name="Theme"
Margin="0,0,0,8"
SelectionChanged="Theme_SelectionChanged">
<ComboBoxItem Content="Default" />
<ComboBoxItem Content="Dark" />
<ComboBoxItem Content="Light" />
</ComboBox>
<muxc:MenuBar>
<muxc:MenuBarItem Title="File">
<MenuFlyoutItem Text="New" />
<MenuFlyoutItem Text="Open..." />
<MenuFlyoutItem Text="Save" />
<MenuFlyoutItem Text="Exit" />
</muxc:MenuBarItem>
<muxc:MenuBarItem Title="Edit">
<MenuFlyoutItem Text="Undo" />
<MenuFlyoutItem Text="Cut" />
<MenuFlyoutItem Text="Copy" />
<MenuFlyoutItem Text="Paste" />
</muxc:MenuBarItem>
<muxc:MenuBarItem Title="Help">
<MenuFlyoutItem Text="About" />
</muxc:MenuBarItem>
</muxc:MenuBar>
<muxc:ProgressRing Margin="0,0,0,8" IsActive="True" />
<muxc:ProgressBar
Width="130"
Margin="0,0,0,8"
IsIndeterminate="True"
ShowError="False"
ShowPaused="False" />
<Button Margin="0,0,0,8" Content="Button" /> <Button Margin="0,0,0,8" Content="Button" />
<Slider Margin="0,0,0,8" /> <Slider Margin="0,0,0,8" />
<TextBox Margin="0,0,0,8" /> <TextBox Margin="0,0,0,8" />
<ToggleButton Margin="0,0,0,8" />
<CalendarView Margin="0,0,0,8" /> <CalendarView Margin="0,0,0,8" />
<TimePicker Margin="0,0,0,8" />
<DatePicker />
<muxc:NumberBox
x:Name="NumberBoxSpinButtonPlacementExample"
Header="Enter an integer:"
LargeChange="100"
SmallChange="10"
SpinButtonPlacementMode="Compact"
Value="1" />
<muxc:RadioButtons Header="Options:">
<RadioButton Content="Option 1" />
<RadioButton Content="Option 2" />
<RadioButton Content="Option 3" />
</muxc:RadioButtons>
<StackPanel>
<CheckBox
x:Name="OptionsAllCheckBox"
Content="Select all"
IsThreeState="True" />
<CheckBox
x:Name="Option1CheckBox"
Margin="24,0,0,0"
Content="Option 1" />
<CheckBox
x:Name="Option2CheckBox"
Margin="24,0,0,0"
Content="Option 2"
IsChecked="True" />
<CheckBox
x:Name="Option3CheckBox"
Margin="24,0,0,0"
Content="Option 3" />
</StackPanel> </StackPanel>
</UserControl> <muxc:RatingControl AutomationProperties.Name="RatingControl with placeholder" PlaceholderValue="0" />
</StackPanel>
</controls:NotificationFlyout>
@@ -1,27 +1,26 @@
using System; namespace NotificationFlyoutSample
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 Shell : UserControl public sealed partial class Shell
{ {
public Shell() public Shell()
{ {
this.InitializeComponent(); InitializeComponent();
}
private void Theme_SelectionChanged(object sender, Windows.UI.Xaml.Controls.SelectionChangedEventArgs e)
{
switch (Theme.SelectedIndex)
{
case 0:
RequestedTheme = Windows.UI.Xaml.ElementTheme.Default;
break;
case 1:
RequestedTheme = Windows.UI.Xaml.ElementTheme.Dark;
break;
case 2:
RequestedTheme = Windows.UI.Xaml.ElementTheme.Light;
break;
}
} }
} }
} }
@@ -6,6 +6,9 @@
xmlns:muxc="using:Microsoft.UI.Xaml.Controls" xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
IconSource="/Assets/Icon.ico" IconSource="/Assets/Icon.ico"
LightIconSource="/Assets/Icon-Light.ico"> LightIconSource="/Assets/Icon-Light.ico">
<controls:NotificationFlyout.ContextMenuItems>
<MenuFlyoutItem Text="Close" />
</controls:NotificationFlyout.ContextMenuItems>
<StackPanel Margin="24"> <StackPanel Margin="24">
<ComboBox <ComboBox
x:Name="Theme" x:Name="Theme"
@@ -8,6 +8,13 @@
<GenerateAssemblyInfo>false</GenerateAssemblyInfo> <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<None Remove="NotificationFlyout\ContextMenuFlyoutHost.xaml" />
</ItemGroup>
<ItemGroup>
<Page Include="NotificationFlyout\ContextMenuFlyoutHost.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="NotificationFlyout\NotificationFlyoutHost.xaml"> <Page Include="NotificationFlyout\NotificationFlyoutHost.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
@@ -0,0 +1,34 @@
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
namespace NotificationFlyout.Uwp.UI.Controls
{
internal class ContextMenuFlyoutHost : Control
{
private Grid _root;
public ContextMenuFlyoutHost()
{
DefaultStyleKey = typeof(ContextMenuFlyoutHost);
}
public void ShowFlyout()
{
if (_root == null) return;
var flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.ShowAt(_root, new FlyoutShowOptions { Placement = FlyoutPlacementMode.BottomEdgeAlignedLeft, ShowMode = FlyoutShowMode.TransientWithDismissOnPointerMoveAway });
}
public void HideFlyout()
{
if (_root == null) return;
var flyout = FlyoutBase.GetAttachedFlyout(_root);
flyout.Hide();
}
protected override void OnApplyTemplate()
{
_root = GetTemplateChild("Root") as Grid;
}
}
}
@@ -0,0 +1,20 @@
<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:ContextMenuFlyoutHost">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:ContextMenuFlyoutHost">
<Grid x:Name="Root">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Test" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -1,5 +1,9 @@
using System; using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Windows.UI.Xaml; using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Markup; using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media; using Windows.UI.Xaml.Media;
@@ -28,9 +32,19 @@ namespace NotificationFlyout.Uwp.UI.Controls
typeof(UIElement), typeof(NotificationFlyout), typeof(UIElement), typeof(NotificationFlyout),
new PropertyMetadata(null, OnContentPropertyChanged)); new PropertyMetadata(null, OnContentPropertyChanged));
public static DependencyProperty ContextMenuItemsProperty =
DependencyProperty.Register(nameof(ContextMenuItems),
typeof(IList<MenuFlyoutItemBase>), typeof(NotificationFlyout),
new PropertyMetadata(null));
internal event EventHandler ContentChanged; internal event EventHandler ContentChanged;
internal event EventHandler RequestedThemeChanged;
internal event EventHandler IconSourceChanged; internal event EventHandler IconSourceChanged;
internal event EventHandler RequestedThemeChanged;
public NotificationFlyout()
{
ContextMenuItems = new ObservableCollection<MenuFlyoutItemBase>();
}
public UIElement Content public UIElement Content
{ {
@@ -38,6 +52,12 @@ namespace NotificationFlyout.Uwp.UI.Controls
set => SetValue(ContentProperty, value); set => SetValue(ContentProperty, value);
} }
public IList<MenuFlyoutItemBase> ContextMenuItems
{
get => (IList<MenuFlyoutItemBase>)GetValue(ContextMenuItemsProperty);
set => SetValue(ContextMenuItemsProperty, value);
}
public ImageSource IconSource public ImageSource IconSource
{ {
get => (ImageSource)GetValue(IconSourceProperty); get => (ImageSource)GetValue(IconSourceProperty);
@@ -6,7 +6,7 @@ using Windows.UI.Xaml.Media;
namespace NotificationFlyout.Uwp.UI.Controls namespace NotificationFlyout.Uwp.UI.Controls
{ {
public class NotificationFlyoutHost : Control internal class NotificationFlyoutHost : Control
{ {
public static readonly DependencyProperty ContentProperty = public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register(nameof(Content), DependencyProperty.Register(nameof(Content),
@@ -2,5 +2,6 @@
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.xaml" /> <ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutHost.xaml" />
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutPresenter.xaml" /> <ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/NotificationFlyoutPresenter.xaml" />
<ResourceDictionary Source="ms-appx:///NotificationFlyout.Uwp.UI.Controls/NotificationFlyout/ContextMenuFlyoutHost.xaml" />
</ResourceDictionary.MergedDictionaries> </ResourceDictionary.MergedDictionaries>
</ResourceDictionary> </ResourceDictionary>
@@ -0,0 +1,25 @@
<Project Sdk="MSBuild.Sdk.Extras">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<AssetTargetFallback>uap10.0.19041</AssetTargetFallback>
<Platforms>AnyCPU;x64</Platforms>
<MSBuildWarningsAsMessages>NU1702</MSBuildWarningsAsMessages>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.XamlHost" Version="6.1.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\NotificationFlyout.Uwp.UI.Controls\NotificationFlyout.Uwp.UI.Controls.csproj" />
<ProjectReference Include="..\NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj" />
<ProjectReference Include="..\NotificationFlyout.Wpf.UI\NotificationFlyout.Wpf.UI.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.VCRTForwarders.140" Version="1.0.7" />
</ItemGroup>
</Project>
@@ -11,11 +11,11 @@ namespace NotificationFlyout.Wpf.UI.Controls
typeof(Uwp.UI.Controls.NotificationFlyout), typeof(NotificationFlyoutApplication), typeof(Uwp.UI.Controls.NotificationFlyout), typeof(NotificationFlyoutApplication),
new PropertyMetadata(null, OnFlyoutPropertyChanged)); new PropertyMetadata(null, OnFlyoutPropertyChanged));
private readonly NotificationFlyoutXamlHost _xamlHost; private readonly NotificationFlyoutXamlHostWindow _xamlHost;
public NotificationFlyoutApplication() public NotificationFlyoutApplication()
{ {
_xamlHost = new NotificationFlyoutXamlHost(); _xamlHost = new NotificationFlyoutXamlHostWindow();
_xamlHost.Show(); _xamlHost.Show();
} }
@@ -0,0 +1,38 @@
using NotificationFlyout.Uwp.UI.Controls;
using NotificationFlyout.Wpf.UI.Extensions;
using NotificationFlyout.Wpf.UI.Helpers;
using System;
namespace NotificationFlyout.Wpf.UI.Controls
{
internal class ContextMenuXamlHost : XamlHostWindow<ContextMenuFlyoutHost>
{
public ContextMenuXamlHost()
{
Topmost = true;
}
protected override void OnDeactivated(EventArgs args)
{
var flyoutHost = GetHostContent();
if (flyoutHost != null)
{
flyoutHost.HideFlyout();
}
}
public void ShowContextMenuFlyout()
{
var position = CursorHelper.GetPhysicalCursorPos();
this.SetWindowPosition(position.y, position.x, WindowSize, WindowSize);
var flyoutHost = GetHostContent();
if (flyoutHost != null)
{
flyoutHost.ShowFlyout();
}
Activate();
}
}
}
@@ -1,32 +1,29 @@
using Microsoft.Toolkit.Wpf.UI.XamlHost; using NotificationFlyout.Uwp.UI.Controls;
using NotificationFlyout.Uwp.UI.Controls;
using NotificationFlyout.Wpf.UI.Extensions; using NotificationFlyout.Wpf.UI.Extensions;
using NotificationFlyout.Uwp.UI.Extensions; using NotificationFlyout.Uwp.UI.Extensions;
using NotificationFlyout.Wpf.UI.Helpers; using NotificationFlyout.Wpf.UI.Helpers;
using System; using System;
using System.Windows; using System.Windows;
using System.Windows.Media;
using Windows.UI.Xaml.Controls.Primitives; using Windows.UI.Xaml.Controls.Primitives;
using System.Windows.Input;
namespace NotificationFlyout.Wpf.UI.Controls namespace NotificationFlyout.Wpf.UI.Controls
{ {
internal class NotificationFlyoutXamlHost : Window internal class NotificationFlyoutXamlHostWindow : XamlHostWindow<NotificationFlyoutHost>
{ {
private const string ShellTrayHandleName = "Shell_TrayWnd"; private const string ShellTrayHandleName = "Shell_TrayWnd";
private const double WindowSize = 5;
private ContextMenuXamlHost _contextMenuXamlHost;
private Uwp.UI.Controls.NotificationFlyout _flyout; private Uwp.UI.Controls.NotificationFlyout _flyout;
private bool _isLoaded; private bool _isLoaded;
private NotificationIconHelper _notificationIconHelper; private NotificationIconHelper _notificationIconHelper;
private SystemPersonalisationHelper _systemPersonalisationHelper; private SystemPersonalisationHelper _systemPersonalisationHelper;
private TaskbarHelper _taskbarHelper; private TaskbarHelper _taskbarHelper;
private WindowsXamlHost _xamlHost;
public NotificationFlyoutXamlHost() public NotificationFlyoutXamlHostWindow()
{ {
PrepareDefaultWindow();
PrepareWindowsXamlHost();
Loaded += OnLoaded; Loaded += OnLoaded;
} }
@@ -51,7 +48,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
internal void HideFlyout() internal void HideFlyout()
{ {
var flyoutHost = GetFlyoutHost(); var flyoutHost = GetHostContent();
if (flyoutHost != null) if (flyoutHost != null)
{ {
flyoutHost.HideFlyout(); flyoutHost.HideFlyout();
@@ -60,7 +57,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
internal void ShowFlyout() internal void ShowFlyout()
{ {
var flyoutHost = GetFlyoutHost(); var flyoutHost = GetHostContent();
if (flyoutHost != null) if (flyoutHost != null)
{ {
var taskbarState = _taskbarHelper.GetCurrentState(); var taskbarState = _taskbarHelper.GetCurrentState();
@@ -78,10 +75,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
} }
} }
private NotificationFlyoutHost GetFlyoutHost() protected override void OnDeactivated(EventArgs args)
{ {
if (_xamlHost == null) return null; HideFlyout();
return _xamlHost.GetUwpInternalObject() as NotificationFlyoutHost;
} }
private void OnFlyoutContentChanged(object sender, EventArgs args) private void OnFlyoutContentChanged(object sender, EventArgs args)
@@ -100,10 +96,18 @@ namespace NotificationFlyout.Wpf.UI.Controls
} }
private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args) private void OnIconInvoked(object sender, NotificationIconInvokedEventArgs args)
{
if (args.MouseButton == MouseButton.Left)
{ {
ShowFlyout(); ShowFlyout();
} }
if (args.MouseButton == MouseButton.Right)
{
ShowContextMenuFlyout();
}
}
private void OnLoaded(object sender, RoutedEventArgs args) private void OnLoaded(object sender, RoutedEventArgs args)
{ {
PrepareNotificationIcon(); PrepareNotificationIcon();
@@ -112,7 +116,6 @@ namespace NotificationFlyout.Wpf.UI.Controls
_isLoaded = true; _isLoaded = true;
UpdateWindow(); UpdateWindow();
this.Hidden();
} }
private void OnTaskbarChanged(object sender, EventArgs args) private void OnTaskbarChanged(object sender, EventArgs args)
@@ -125,20 +128,11 @@ namespace NotificationFlyout.Wpf.UI.Controls
UpdateIcons(); UpdateIcons();
} }
private void PrepareDefaultWindow()
{
ShowInTaskbar = false;
ShowActivated = false;
WindowStyle = WindowStyle.None;
ResizeMode = ResizeMode.NoResize;
AllowsTransparency = true;
Background = new SolidColorBrush(Colors.Transparent);
Height = WindowSize;
Width = WindowSize;
}
private void PrepareNotificationIcon() private void PrepareNotificationIcon()
{ {
_contextMenuXamlHost = new ContextMenuXamlHost();
_contextMenuXamlHost.Show();
_notificationIconHelper = NotificationIconHelper.Create(this); _notificationIconHelper = NotificationIconHelper.Create(this);
_notificationIconHelper.IconInvoked += OnIconInvoked; _notificationIconHelper.IconInvoked += OnIconInvoked;
@@ -151,20 +145,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
_taskbarHelper = TaskbarHelper.Create(this); _taskbarHelper = TaskbarHelper.Create(this);
_taskbarHelper.TaskbarChanged += OnTaskbarChanged; _taskbarHelper.TaskbarChanged += OnTaskbarChanged;
} }
private void ShowContextMenuFlyout()
private void PrepareWindowsXamlHost()
{ {
_xamlHost = new WindowsXamlHost _contextMenuXamlHost.ShowContextMenuFlyout();
{
InitialTypeName = typeof(NotificationFlyoutHost).FullName
};
_xamlHost.Height = 0;
_xamlHost.Width = 0;
_xamlHost.HorizontalAlignment = HorizontalAlignment.Stretch;
_xamlHost.VerticalAlignment = VerticalAlignment.Stretch;
Content = _xamlHost;
} }
private void UpdateFlyoutContent() private void UpdateFlyoutContent()
@@ -174,7 +157,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
var content = _flyout.Content; var content = _flyout.Content;
if (content == null) return; if (content == null) return;
var flyoutHost = GetFlyoutHost(); var flyoutHost = GetHostContent();
if (flyoutHost != null) if (flyoutHost != null)
{ {
flyoutHost.Content = content; flyoutHost.Content = content;
@@ -208,7 +191,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
var requestedTheme = _flyout.RequestedTheme; var requestedTheme = _flyout.RequestedTheme;
var flyoutHost = GetFlyoutHost(); var flyoutHost = GetHostContent();
if (flyoutHost != null) if (flyoutHost != null)
{ {
flyoutHost.RequestedTheme = requestedTheme; flyoutHost.RequestedTheme = requestedTheme;
@@ -219,7 +202,7 @@ namespace NotificationFlyout.Wpf.UI.Controls
{ {
if (!_isLoaded) return; if (!_isLoaded) return;
var flyoutHost = GetFlyoutHost(); var flyoutHost = GetHostContent();
if (flyoutHost == null) return; if (flyoutHost == null) return;
var taskbarState = _taskbarHelper.GetCurrentState(); var taskbarState = _taskbarHelper.GetCurrentState();
@@ -0,0 +1,60 @@
using Microsoft.Toolkit.Wpf.UI.XamlHost;
using NotificationFlyout.Wpf.UI.Extensions;
using System.Windows;
using System.Windows.Media;
namespace NotificationFlyout.Wpf.UI.Controls
{
internal class XamlHostWindow<TXamlContent> : Window where TXamlContent : class
{
internal const double WindowSize = 5;
private WindowsXamlHost _xamlHost;
public XamlHostWindow()
{
PrepareDefaultWindow();
PrepareWindowsXamlHost();
Loaded += OnLoaded;
}
internal TXamlContent GetHostContent()
{
if (_xamlHost == null) return null;
return _xamlHost.GetUwpInternalObject() as TXamlContent;
}
private void OnLoaded(object sender, RoutedEventArgs args)
{
this.Hidden();
}
private void PrepareDefaultWindow()
{
ShowInTaskbar = false;
ShowActivated = false;
WindowStyle = WindowStyle.None;
ResizeMode = ResizeMode.NoResize;
AllowsTransparency = true;
Background = new SolidColorBrush(Colors.Red);
Height = WindowSize;
Width = WindowSize;
}
private void PrepareWindowsXamlHost()
{
_xamlHost = new WindowsXamlHost
{
InitialTypeName = typeof(TXamlContent).FullName
};
_xamlHost.Height = 0;
_xamlHost.Width = 0;
_xamlHost.HorizontalAlignment = HorizontalAlignment.Stretch;
_xamlHost.VerticalAlignment = VerticalAlignment.Stretch;
Content = _xamlHost;
}
}
}
@@ -0,0 +1,13 @@
using Microsoft.Windows.Sdk;
namespace NotificationFlyout.Wpf.UI.Helpers
{
internal class CursorHelper
{
public static POINT GetPhysicalCursorPos()
{
PInvoke.GetPhysicalCursorPos(out POINT point);
return point;
}
}
}
@@ -1,5 +1,5 @@
using Microsoft.Windows.Sdk; using System;
using System; using Microsoft.Windows.Sdk;
namespace NotificationFlyout.Wpf.UI.Helpers namespace NotificationFlyout.Wpf.UI.Helpers
{ {
@@ -1,13 +1,13 @@
Shell_NotifyIcon Shell_NotifyIcon
GetDpiForWindow
FindWindow
GetSystemMetricsForDpi GetSystemMetricsForDpi
DefWindowProcW DefWindowProcW
GetSystemMetrics GetSystemMetrics
MonitorFromWindow MonitorFromWindow
RegisterWindowMessage RegisterWindowMessage
FindWindow
SHAppBarMessage SHAppBarMessage
SetWindowPos SetWindowPos
GetWindowLong GetWindowLong
SetWindowLong SetWindowLong
GetDpiForWindow
FindWindow
GetPhysicalCursorPos
@@ -0,0 +1,3 @@
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("NotificationFlyout.Wpf.UI.Controls")]
+1
View File
@@ -88,6 +88,7 @@ namespace NotificationFlyout.Wpf.UI
return monitorData; return monitorData;
} }
private Rect GetWorkingArea() private Rect GetWorkingArea()
{ {
if (!_multiMonitorSupport || _monitorHandle == (IntPtr)PRIMARY_MONITOR) if (!_multiMonitorSupport || _monitorHandle == (IntPtr)PRIMARY_MONITOR)
+1 -1
View File
@@ -14,7 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
global.json = global.json global.json = global.json
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotificationFlyout.Uwp.UI", "NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj", "{3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NotificationFlyout.Uwp.UI", "NotificationFlyout.Uwp.UI\NotificationFlyout.Uwp.UI.csproj", "{3FE0D7F7-1173-4989-BE6C-AD28FE0D4AC9}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution