Use VisualStates to manage the placement of the flyout
This commit is contained in:
@@ -2,8 +2,7 @@
|
|||||||
x:Class="NotificationFlyout.Sample.NotificationFlyoutPresenter"
|
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"
|
xmlns:controls="using:NotificationFlyout.Uwp.UI.Controls">
|
||||||
CornerRadius="4">
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<ListBox
|
<ListBox
|
||||||
Width="300"
|
Width="300"
|
||||||
|
|||||||
@@ -122,7 +122,6 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="NotificationFlyoutHost\NotificationFlyoutHost.cs" />
|
<Compile Include="NotificationFlyoutHost\NotificationFlyoutHost.cs" />
|
||||||
<Compile Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.cs" />
|
<Compile Include="NotificationFlyoutPresenter\NotificationFlyoutPresenter.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>
|
||||||
|
|||||||
+13
-21
@@ -11,20 +11,13 @@ namespace NotificationFlyout.Uwp.UI.Controls
|
|||||||
typeof(NotificationFlyoutPresenter), typeof(NotificationFlyoutHost),
|
typeof(NotificationFlyoutPresenter), typeof(NotificationFlyoutHost),
|
||||||
new PropertyMetadata(null));
|
new PropertyMetadata(null));
|
||||||
|
|
||||||
public static readonly DependencyProperty TemplateSettingsProperty =
|
private bool _isLoaded;
|
||||||
DependencyProperty.Register(nameof(TemplateSettings),
|
private string _placement;
|
||||||
typeof(NotificationFlyoutHostTemplateSettings), typeof(NotificationFlyoutHost),
|
|
||||||
new PropertyMetadata(null));
|
|
||||||
|
|
||||||
private readonly NotificationFlyoutHostTemplateSettings _templateSettings;
|
|
||||||
private Grid _root;
|
private Grid _root;
|
||||||
|
|
||||||
public NotificationFlyoutHost()
|
public NotificationFlyoutHost()
|
||||||
{
|
{
|
||||||
DefaultStyleKey = typeof(NotificationFlyoutHost);
|
DefaultStyleKey = typeof(NotificationFlyoutHost);
|
||||||
|
|
||||||
_templateSettings = new NotificationFlyoutHostTemplateSettings();
|
|
||||||
SetValue(TemplateSettingsProperty, _templateSettings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotificationFlyoutPresenter FlyoutPresenter
|
public NotificationFlyoutPresenter FlyoutPresenter
|
||||||
@@ -33,12 +26,6 @@ namespace NotificationFlyout.Uwp.UI.Controls
|
|||||||
set => SetValue(FlyoutPresenterProperty, value);
|
set => SetValue(FlyoutPresenterProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NotificationFlyoutHostTemplateSettings TemplateSettings
|
|
||||||
{
|
|
||||||
get => (NotificationFlyoutHostTemplateSettings)GetValue(TemplateSettingsProperty);
|
|
||||||
set => SetValue(TemplateSettingsProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void HideFlyout()
|
public void HideFlyout()
|
||||||
{
|
{
|
||||||
if (_root == null) return;
|
if (_root == null) return;
|
||||||
@@ -46,11 +33,14 @@ namespace NotificationFlyout.Uwp.UI.Controls
|
|||||||
flyout.Hide();
|
flyout.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetOffset(double verticalOffset, double horizontalOffset)
|
public void SetFlyoutPlacement(string placement)
|
||||||
{
|
{
|
||||||
if (_templateSettings == null) return;
|
if (!_isLoaded)
|
||||||
_templateSettings.FromVerticalOffset = verticalOffset;
|
{
|
||||||
_templateSettings.FromHorizontalOffset = horizontalOffset;
|
_placement = placement;
|
||||||
|
}
|
||||||
|
|
||||||
|
VisualStateManager.GoToState(this, placement, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ShowFlyout(FlyoutPlacementMode placementMode)
|
public void ShowFlyout(FlyoutPlacementMode placementMode)
|
||||||
@@ -60,13 +50,15 @@ namespace NotificationFlyout.Uwp.UI.Controls
|
|||||||
flyout.ShowAt(_root, new FlyoutShowOptions
|
flyout.ShowAt(_root, new FlyoutShowOptions
|
||||||
{
|
{
|
||||||
Placement = placementMode,
|
Placement = placementMode,
|
||||||
ShowMode = FlyoutShowMode.Standard
|
ShowMode = FlyoutShowMode.Standard,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnApplyTemplate()
|
protected override void OnApplyTemplate()
|
||||||
{
|
{
|
||||||
_root = GetTemplateChild("Root") as Grid;
|
_root = GetTemplateChild("Root") as Grid;
|
||||||
|
_isLoaded = true;
|
||||||
|
SetFlyoutPlacement(_placement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+79
-11
@@ -7,20 +7,88 @@
|
|||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<ControlTemplate TargetType="controls:NotificationFlyoutHost">
|
<ControlTemplate TargetType="controls:NotificationFlyoutHost">
|
||||||
<Grid x:Name="Root">
|
<Grid x:Name="Root">
|
||||||
|
<Grid.Resources>
|
||||||
|
<Style x:Key="DefaultFlyoutPresenterStyle" TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="IsDefaultShadowEnabled" Value="False" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
</Style>
|
||||||
|
<Style
|
||||||
|
x:Key="TopFlyoutPresenterStyle"
|
||||||
|
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||||
|
TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="Margin" Value="0,-5,0,0" />
|
||||||
|
</Style>
|
||||||
|
<Style
|
||||||
|
x:Key="BottomFlyoutPresenterStyle"
|
||||||
|
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||||
|
TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="Margin" Value="0,5,0,0" />
|
||||||
|
</Style>
|
||||||
|
<Style
|
||||||
|
x:Key="LeftFlyoutPresenterStyle"
|
||||||
|
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||||
|
TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="Margin" Value="-5,0,0,0" />
|
||||||
|
</Style>
|
||||||
|
<Style
|
||||||
|
x:Key="RightFlyoutPresenterStyle"
|
||||||
|
BasedOn="{StaticResource DefaultFlyoutPresenterStyle}"
|
||||||
|
TargetType="FlyoutPresenter">
|
||||||
|
<Setter Property="Margin" Value="5,0,0,0" />
|
||||||
|
</Style>
|
||||||
|
</Grid.Resources>
|
||||||
<FlyoutBase.AttachedFlyout>
|
<FlyoutBase.AttachedFlyout>
|
||||||
<Flyout AreOpenCloseAnimationsEnabled="False" ShouldConstrainToRootBounds="False">
|
<Flyout
|
||||||
<Flyout.FlyoutPresenterStyle>
|
x:Name="Flyout"
|
||||||
<Style TargetType="FlyoutPresenter">
|
AreOpenCloseAnimationsEnabled="False"
|
||||||
<Setter Property="BorderThickness" Value="0" />
|
FlyoutPresenterStyle="{StaticResource BottomFlyoutPresenterStyle}"
|
||||||
<Setter Property="Background" Value="Transparent" />
|
ShouldConstrainToRootBounds="False">
|
||||||
<Setter Property="IsDefaultShadowEnabled" Value="False" />
|
<ContentControl Content="{TemplateBinding FlyoutPresenter}">
|
||||||
<Setter Property="Padding" Value="0" />
|
<ContentControl.Transitions>
|
||||||
<Setter Property="Margin" Value="0" />
|
<TransitionCollection>
|
||||||
</Style>
|
<EntranceThemeTransition
|
||||||
</Flyout.FlyoutPresenterStyle>
|
x:Name="EntranceThemeTransition"
|
||||||
<ContentControl Content="{TemplateBinding FlyoutPresenter}" />
|
FromHorizontalOffset="0"
|
||||||
|
FromVerticalOffset="0" />
|
||||||
|
</TransitionCollection>
|
||||||
|
</ContentControl.Transitions>
|
||||||
|
</ContentControl>
|
||||||
</Flyout>
|
</Flyout>
|
||||||
</FlyoutBase.AttachedFlyout>
|
</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>
|
</Grid>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
|
|||||||
-29
@@ -1,29 +0,0 @@
|
|||||||
using Windows.UI.Xaml;
|
|
||||||
|
|
||||||
namespace NotificationFlyout.Uwp.UI.Controls
|
|
||||||
{
|
|
||||||
public class NotificationFlyoutHostTemplateSettings : DependencyObject
|
|
||||||
{
|
|
||||||
public static readonly DependencyProperty FromHorizontalOffsetProperty =
|
|
||||||
DependencyProperty.Register(nameof(FromHorizontalOffset),
|
|
||||||
typeof(double), typeof(NotificationFlyoutHostTemplateSettings),
|
|
||||||
new PropertyMetadata(0d));
|
|
||||||
|
|
||||||
public static readonly DependencyProperty FromVerticalOffsetProperty =
|
|
||||||
DependencyProperty.Register(nameof(FromVerticalOffset),
|
|
||||||
typeof(double), typeof(NotificationFlyoutHostTemplateSettings),
|
|
||||||
new PropertyMetadata(0d));
|
|
||||||
|
|
||||||
public double FromHorizontalOffset
|
|
||||||
{
|
|
||||||
get => (double)GetValue(FromHorizontalOffsetProperty);
|
|
||||||
set => SetValue(FromHorizontalOffsetProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double FromVerticalOffset
|
|
||||||
{
|
|
||||||
get => (double)GetValue(FromVerticalOffsetProperty);
|
|
||||||
set => SetValue(FromVerticalOffsetProperty, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-5
@@ -14,11 +14,6 @@
|
|||||||
BorderBrush="{TemplateBinding BorderBrush}"
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
BorderThickness="{TemplateBinding BorderThickness}"
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
CornerRadius="{TemplateBinding CornerRadius}">
|
CornerRadius="{TemplateBinding CornerRadius}">
|
||||||
<Border.Transitions>
|
|
||||||
<TransitionCollection>
|
|
||||||
<EntranceThemeTransition FromHorizontalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.FromHorizontalOffset, Mode=TwoWay}" FromVerticalOffset="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.FromVerticalOffset, Mode=TwoWay}" />
|
|
||||||
</TransitionCollection>
|
|
||||||
</Border.Transitions>
|
|
||||||
<ScrollViewer
|
<ScrollViewer
|
||||||
x:Name="ScrollViewer"
|
x:Name="ScrollViewer"
|
||||||
AutomationProperties.AccessibilityView="Raw"
|
AutomationProperties.AccessibilityView="Raw"
|
||||||
|
|||||||
+10
-23
@@ -88,10 +88,6 @@ namespace NotificationFlyout.Wpf.UI.Controls
|
|||||||
|
|
||||||
private void OnTaskbarChanged(object sender, EventArgs args)
|
private void OnTaskbarChanged(object sender, EventArgs args)
|
||||||
{
|
{
|
||||||
var taskbarState = _taskbarHelper.GetCurrentState();
|
|
||||||
Left = taskbarState.Screen.WorkingArea.Left;
|
|
||||||
Top = taskbarState.Screen.WorkingArea.Top;
|
|
||||||
|
|
||||||
UpdateWindow();
|
UpdateWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,9 +98,9 @@ namespace NotificationFlyout.Wpf.UI.Controls
|
|||||||
WindowStyle = WindowStyle.None;
|
WindowStyle = WindowStyle.None;
|
||||||
ResizeMode = ResizeMode.NoResize;
|
ResizeMode = ResizeMode.NoResize;
|
||||||
AllowsTransparency = true;
|
AllowsTransparency = true;
|
||||||
Background = new SolidColorBrush(Colors.Transparent);
|
Background = new SolidColorBrush(Colors.Red);
|
||||||
Height = 5;
|
Height = 0;
|
||||||
Width = 5;
|
Width = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrepareNotificationIcon()
|
private void PrepareNotificationIcon()
|
||||||
@@ -139,19 +135,14 @@ namespace NotificationFlyout.Wpf.UI.Controls
|
|||||||
|
|
||||||
var taskbarState = _taskbarHelper.GetCurrentState();
|
var taskbarState = _taskbarHelper.GetCurrentState();
|
||||||
|
|
||||||
var screen = Screen.FromHandle(this.GetHandle());
|
Left = taskbarState.Screen.WorkingArea.Left;
|
||||||
MaxHeight = screen.Bounds.Height / 2;
|
Top = taskbarState.Screen.WorkingArea.Top;
|
||||||
|
|
||||||
var windowWidth = DesiredSize.Width * this.DpiX();
|
var windowWidth = 0 * this.DpiX();
|
||||||
var windowHeight = DesiredSize.Height * this.DpiY();
|
var windowHeight = 0 * this.DpiY();
|
||||||
|
|
||||||
double top;
|
|
||||||
double left;
|
|
||||||
double height;
|
|
||||||
double width;
|
|
||||||
double verticalOffset = 0;
|
|
||||||
double horizontalOffset = 0;
|
|
||||||
|
|
||||||
|
double top, left, height, width;
|
||||||
|
|
||||||
var taskbarRect = taskbarState.Rect;
|
var taskbarRect = taskbarState.Rect;
|
||||||
switch (taskbarState.Position)
|
switch (taskbarState.Position)
|
||||||
{
|
{
|
||||||
@@ -160,35 +151,31 @@ namespace NotificationFlyout.Wpf.UI.Controls
|
|||||||
left = taskbarRect.Right;
|
left = taskbarRect.Right;
|
||||||
height = windowHeight;
|
height = windowHeight;
|
||||||
width = windowWidth;
|
width = windowWidth;
|
||||||
horizontalOffset = -MaximumOffset;
|
|
||||||
break;
|
break;
|
||||||
case TaskbarPosition.Top:
|
case TaskbarPosition.Top:
|
||||||
top = taskbarRect.Bottom;
|
top = taskbarRect.Bottom;
|
||||||
left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth;
|
left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth;
|
||||||
height = windowHeight;
|
height = windowHeight;
|
||||||
width = windowWidth;
|
width = windowWidth;
|
||||||
verticalOffset = -MaximumOffset;
|
|
||||||
break;
|
break;
|
||||||
case TaskbarPosition.Right:
|
case TaskbarPosition.Right:
|
||||||
top = taskbarRect.Bottom - windowHeight;
|
top = taskbarRect.Bottom - windowHeight;
|
||||||
left = taskbarRect.Left - windowWidth;
|
left = taskbarRect.Left - windowWidth;
|
||||||
height = windowHeight;
|
height = windowHeight;
|
||||||
width = windowWidth;
|
width = windowWidth;
|
||||||
horizontalOffset = MaximumOffset;
|
|
||||||
break;
|
break;
|
||||||
case TaskbarPosition.Bottom:
|
case TaskbarPosition.Bottom:
|
||||||
top = taskbarRect.Top - windowHeight;
|
top = taskbarRect.Top - windowHeight;
|
||||||
left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth;
|
left = FlowDirection == FlowDirection.RightToLeft ? taskbarRect.Left : taskbarRect.Right - windowWidth;
|
||||||
height = windowHeight;
|
height = windowHeight;
|
||||||
width = windowWidth;
|
width = windowWidth;
|
||||||
verticalOffset = MaximumOffset;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.SetWindowPosition(top, left, height, width);
|
this.SetWindowPosition(top, left, height, width);
|
||||||
flyoutHost.SetOffset(verticalOffset, horizontalOffset);
|
flyoutHost.SetFlyoutPlacement(taskbarState.Position.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user