Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adjust Flyout position when it has been automatically repositioned

Tags:

c#

xaml

uwp

See a demo here

See a demo here.

I have a UWP app that has a ListView with selectable list items as shown. Selecting the right side of the item opens a Flyout (not a MenuFlyout). I specify the Placement of the Flyout to be Bottom, and a Margin of 0, -4, 0, 0 in the FlyoutPresenter Style. This results in the desired appearance, with the Flyout directly below and adjacent to the item.

However, if there isn't enough room to display the Flyout, it will be automatically moved to a Placement of Top. Even if I define the margin of the FlyoutPresenter Style to have -4 bottom margin, it doesn't appear to be applied.

Is there a way to move the Flyout? I'd prefer not to use a MenuFlyout if possible, since nothing is meant to be selectable. Flyouts don't have a Canvas attached property, and updating the Canvas.Top position of the top-most child of the Flyout didn't work (and I didn't really expect it to).

Edit: The desired behavior is for the Flyout to appear in the Top Placement, as is happening, but without the space in between the Flyout and the Target.

like image 783
Tyler Southard Avatar asked Dec 16 '25 13:12

Tyler Southard


1 Answers

According to Placing a Flyout section of Quickstart: Adding a Flyout:

The flyout is shown using the preferred placement if there's space for it on the screen. If there isn’t enough space, like when the element is near the edge of the screen, the flyout is placed using this fallback order.

When the placement is set to bottom, if there is no enough space it will place on the top which is by designed.

but without the space in between the Flyout and the Target

If the bottom has no enough space, the Flyout place on the top, at this time, the margin of FlyoutPresenter should be changed to 0,4,0,0 instead of 0,-4,0,0 to access the same effects as it is on the bottom. But you will not know whether the Flyout is place top or bottom, so as a workaround you can set margin to 0,-5,0,-5for the Border element inside the control template of FlyoutPresenterStyle which can meet your requirements. For example:

<Button
        Canvas.Top="600"
        HorizontalAlignment="Center"
        VerticalAlignment="Bottom"
        Click="Button_Click"
        Content="Open flyout">
        <Button.Flyout>
            <Flyout x:Name="flyout" Placement="Bottom">
                <Flyout.FlyoutPresenterStyle>
                    <Style TargetType="FlyoutPresenter">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="FlyoutPresenter">
                                    <Border
                                        Margin="0,-5,0,-5"
                                        Background="{TemplateBinding Background}"
                                        BorderBrush="{TemplateBinding BorderBrush}"
                                        BorderThickness="{TemplateBinding BorderThickness}">
                                        <ScrollViewer
                                            x:Name="ScrollViewer"
                                            AutomationProperties.AccessibilityView="Raw"
                                            HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                            HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                            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>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </Flyout.FlyoutPresenterStyle>
                <TextBlock Text="This is some text in a flyout." TextWrapping="Wrap" />
            </Flyout>
        </Button.Flyout>
    </Button>
like image 63
Sunteen Wu Avatar answered Dec 19 '25 02:12

Sunteen Wu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!