DrawerFlyoutPresenter
Summary
DrawerFlyoutPresenter
is a special ContentPresenter
to be used in the template of a FlyoutPresenter
to enable gesture support.
Remarks
All of the properties below can be used both as a dependency property or as an attached property, much like the ScrollViewer
properties:
xmlns:utu="using:Uno.Toolkit.UI"
<Style x:Key="CustomDrawerFlyoutPresenterStyle"
BasedOn="{StaticResource DrawerFlyoutPresenterStyle}"
TargetType="FlyoutPresenter">
<Setter Property="utu:DrawerFlyoutPresenter.OpenDirection" Value="Up" />
<Setter Property="utu:DrawerFlyoutPresenter.DrawerLength" Value="0.66*" />
<Setter Property="utu:DrawerFlyoutPresenter.LightDismissOverlayBackground" Value="#80808080" />
<Setter Property="utu:DrawerFlyoutPresenter.IsGestureEnabled" Value="True" />
<Setter Property="utu:DrawerFlyoutPresenter.IsLightDismissEnabled" Value="True" />
</Style>
<!-- and/or -->
<utu:DrawerFlyoutPresenter OpenDirection="Up"
DrawerLength="0.66*"
LightDismissOverlayBackground="#80808080"
IsGestureEnabled="True"
IsLightDismissEnabled="True" />
Important
There is currently a bug on windows that prevents the usage of attached property style setters. The workaround is to add the following code in your application:
<!--
microsoft/microsoft-ui-xaml#6388 (winui, and on windows only):
If you define attached property setter on a style with BasedOn another style with Template defined from a separate class library
it will throw when the template is materialized:
> Failed to assign to property 'Uno.Toolkit.UI.DrawerFlyoutPresenter.OpenDirection'.
^ It will mention the first attached property used in the template, regardless of which attached property setter that triggered it.
The workaround here is to define the template in the consuming assembly again.
It doesn't matter if it is used or not.
-->
<win:Style x:Key="MUX6388_Workaround_ForDefinitionOnly" TargetType="FlyoutPresenter">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="FlyoutPresenter">
<!-- This is not the full template, we are just making explicit reference to these definitions below -->
<utu:DrawerFlyoutPresenter OpenDirection="{TemplateBinding utu:DrawerFlyoutPresenter.OpenDirection}"
DrawerLength="{TemplateBinding utu:DrawerFlyoutPresenter.DrawerLength}"
LightDismissOverlayBackground="{TemplateBinding utu:DrawerFlyoutPresenter.LightDismissOverlayBackground}"
IsGestureEnabled="{TemplateBinding utu:DrawerFlyoutPresenter.IsGestureEnabled}"
IsLightDismissEnabled="{TemplateBinding utu:DrawerFlyoutPresenter.IsLightDismissEnabled}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</win:Style>
Properties
Property | Type | Description |
---|---|---|
OpenDirection |
DrawerOpenDirection =Up |
Gets or sets the direction in which the drawer opens toward. note: The position of drawer when opened is the opposite of this value. |
DrawerLength |
GridLength =0.66* |
Get or sets the length (width or height depending on the OpenDirection ) of the drawer.* |
LightDismissOverlayBackground |
Brush |
Gets or sets the brush used to paint the light dismiss overlay. The default value is #80808080 (from the default style). |
IsGestureEnabled |
bool =true |
Get or sets a value that indicates whether the user can interact with the control using gesture. |
IsLightDismissEnabled |
bool =true |
Gets or sets a value that indicates whether the drawer flyout can be light-dismissed. |
notes:
For DrawerLength, this value has 3 mode based on
GridUnitType
:<Style TargetType="FlyoutPresenter"> <Setter Property="utu:DrawerFlyoutPresenter.DrawerLength" Value="Auto" /> <Setter Property="utu:DrawerFlyoutPresenter.DrawerLength" Value="0.66*" /> <Setter Property="utu:DrawerFlyoutPresenter.DrawerLength" Value="150" /> <!-- and/or --> <DrawerFlyoutPresenter DrawerLength="Auto" /> <DrawerFlyoutPresenter DrawerLength="0.66*" /> <DrawerFlyoutPresenter DrawerLength="150" />
GridUnitType.Auto
: Fit to flyout content.GridUnitType.Star
: At given ratio of screen/flyout width or height. Valid range is between 0* and 1*, excluding 0* itself.GridUnitType.Pixel
: Fixed at the given value.
Usage
To use this, simply use a Flyout
with Placement="Full"
and one of the followings as the FlyoutPresenterStyle
.
Note
The name prefix here indicates the initial position of the drawer (where it opens from). The open animation direction (OpenDirection
) is the opposite.
LeftDrawerFlyoutPresenterStyle
(OpenDirection=Right)TopDrawerFlyoutPresenterStyle
(OpenDirection=Down)RightDrawerFlyoutPresenterStyle
(OpenDirection=Left)BottomDrawerFlyoutPresenterStyle
(OpenDirection=Up)
Example:
<Button Content="Bottom Drawer"
xmlns:toolkit="using:Uno.UI.Toolkit">
<Button.Flyout>
<Flyout Placement="Full" FlyoutPresenterStyle="{StaticResource BottomDrawerFlyoutPresenterStyle}">
<StackPanel toolkit:VisibleBoundsPadding.PaddingMask="All"
Background="SkyBlue"
MinHeight="200">
<TextBlock Text="text" />
<Button Content="button" />
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
Note
Here VisibleBoundsPadding.PaddingMask
is used to prevent the content from being placed outside of the user-interactable area on mobile devices.
Extended Use Cases
Rounded Corner
<Flyout Placement="Full"> <Flyout.FlyoutPresenterStyle> <Style BasedOn="{StaticResource BottomDrawerFlyoutPresenterStyle}" TargetType="FlyoutPresenter"> <Setter Property="CornerRadius" Value="16,16,0,0" /> </Style> </Flyout.FlyoutPresenterStyle> <Border toolkit:VisibleBoundsPadding.PaddingMask="All" Padding="16,16,0,0"> <!-- flyout content --> </Border> </Flyout>
Note
Padding
is used on the flyout content to avoid content being clipped.Custom background
<Flyout Placement="Full"> <Flyout.FlyoutPresenterStyle> <Style BasedOn="{StaticResource BottomDrawerFlyoutPresenterStyle}" TargetType="FlyoutPresenter"> <Setter Property="Background" Value="SkyBlue" /> </Style> </Flyout.FlyoutPresenterStyle> <Border toolkit:VisibleBoundsPadding.PaddingMask="All" > <!-- flyout content --> </Border> </Flyout>
Warning
Avoid setting
Background
directly on the flyout content:<Border toolkit:VisibleBoundsPadding.PaddingMask="All" Background="SkyBlue">
Instead,
Background
should be set from style setter to avoid edge bleeding on certain platforms, and to avoid default background being painted on the rounded corners.