Use VisualStates to manage the placement of the flyout

This commit is contained in:
Daniel Clark
2021-02-06 21:53:43 +00:00
parent 6558c262c4
commit 3232f1ac77
7 changed files with 103 additions and 92 deletions
@@ -11,20 +11,13 @@ namespace NotificationFlyout.Uwp.UI.Controls
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 bool _isLoaded;
private string _placement;
private Grid _root;
public NotificationFlyoutHost()
{
DefaultStyleKey = typeof(NotificationFlyoutHost);
_templateSettings = new NotificationFlyoutHostTemplateSettings();
SetValue(TemplateSettingsProperty, _templateSettings);
}
public NotificationFlyoutPresenter FlyoutPresenter
@@ -33,12 +26,6 @@ namespace NotificationFlyout.Uwp.UI.Controls
set => SetValue(FlyoutPresenterProperty, value);
}
public NotificationFlyoutHostTemplateSettings TemplateSettings
{
get => (NotificationFlyoutHostTemplateSettings)GetValue(TemplateSettingsProperty);
set => SetValue(TemplateSettingsProperty, value);
}
public void HideFlyout()
{
if (_root == null) return;
@@ -46,11 +33,14 @@ namespace NotificationFlyout.Uwp.UI.Controls
flyout.Hide();
}
public void SetOffset(double verticalOffset, double horizontalOffset)
public void SetFlyoutPlacement(string placement)
{
if (_templateSettings == null) return;
_templateSettings.FromVerticalOffset = verticalOffset;
_templateSettings.FromHorizontalOffset = horizontalOffset;
if (!_isLoaded)
{
_placement = placement;
}
VisualStateManager.GoToState(this, placement, true);
}
public void ShowFlyout(FlyoutPlacementMode placementMode)
@@ -60,13 +50,15 @@ namespace NotificationFlyout.Uwp.UI.Controls
flyout.ShowAt(_root, new FlyoutShowOptions
{
Placement = placementMode,
ShowMode = FlyoutShowMode.Standard
});
ShowMode = FlyoutShowMode.Standard,
});
}
protected override void OnApplyTemplate()
{
_root = GetTemplateChild("Root") as Grid;
_isLoaded = true;
SetFlyoutPlacement(_placement);
}
}
}
@@ -7,20 +7,88 @@
<Setter.Value>
<ControlTemplate TargetType="controls:NotificationFlyoutHost">
<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>
<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
x:Name="Flyout"
AreOpenCloseAnimationsEnabled="False"
FlyoutPresenterStyle="{StaticResource BottomFlyoutPresenterStyle}"
ShouldConstrainToRootBounds="False">
<ContentControl Content="{TemplateBinding FlyoutPresenter}">
<ContentControl.Transitions>
<TransitionCollection>
<EntranceThemeTransition
x:Name="EntranceThemeTransition"
FromHorizontalOffset="0"
FromVerticalOffset="0" />
</TransitionCollection>
</ContentControl.Transitions>
</ContentControl>
</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>
@@ -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);
}
}
}