Share via

MAUI: Issue with FlowDirection

Sreenivasan, Sreejith 840 Reputation points
2025-11-28T07:58:55.85+00:00

My home page is a FlyoutPage and its FlowDirection is RightToLeft, because I need to open the flyout(menu pop up) from the right side. The detail page is TabbedPage with 3 children. The first child is an AlertsPage and if we click on any alert it will open a new page named it as AlertDetailPage. I have UI issues on this AlertDetailPage.

Please check the below screenshots:

Issue 1: Back arrow is showing right of title instead of left and more icon is showing left instead of right.

a

Issue 2: When we click on more icon it shows 2 options like below, it is right aligned, it should be aligned to left.

b

If I remove the FlyoutPage's FlowDirection, all the above UI issues are gone, but the menu is opening from left side. How can I fix this issue? I need to open the menu from right side and need to fix the above alignment issues.

I tried setting FlowDirection LeftToRight for AlertDetailPage xaml, cs and FlyoutPage.Detail, MenuPage but none of them works.

Developer technologies | .NET | .NET Multi-platform App UI

Answer accepted by question author

Michael Le (WICLOUD CORPORATION) 11,325 Reputation points Microsoft External Staff Moderator
2025-12-18T09:34:15.4166667+00:00

Hello @Sreenivasan, Sreejith ,

You can take a look at this implementation:

Inside AlertDetailPage.xaml

<Grid RowDefinitions="Auto,*">
    <!-- Row 0: Custom Toolbar -->
    <Grid BackgroundColor="Primary" 
          HeightRequest="56" 
          FlowDirection="LeftToRight">

        <ColumnDefinitions>
            <ColumnDefinition Width="56" />   <!-- Back -->
            <ColumnDefinition Width="*" />     <!-- Title -->
            <ColumnDefinition Width="56" />    <!-- Menu -->
        </ColumnDefinitions>

        <!-- 3 Elements in toolbar -->
        <!-- Back Button (Always on Left in LTR) -->
        <Button Grid.Column="0"
                Text="←"
                FontSize="28"
                BackgroundColor="Transparent"
                TextColor="White"
                Padding="0"
                Margin="8,0,0,0"
                Clicked="OnBackButtonClicked"
                VerticalOptions="Center"
                HorizontalOptions="Center"
                WidthRequest="40"
                HeightRequest="40" />

        <!-- Title -->
        <Label Grid.Column="1"
                Text="{Binding CurrentNotification.Title}"
                TextColor="White"
                FontSize="18"
                FontAttributes="Bold"
                VerticalOptions="Center"
                HorizontalOptions="Start"
                Margin="8,0,8,0"
                LineBreakMode="TailTruncation"
                MaxLines="1" />

        <!-- Three-Dot Menu Button (Always on Right in LTR) -->
        <ImageButton Grid.Column="2"
                        Source="gui_three_dots.png"
                        BackgroundColor="Transparent"
                        Padding="12"
                        Command="{Binding MoreCommand}"
                        VerticalOptions="Center"
                        HorizontalOptions="Center"
                        WidthRequest="40"
                        HeightRequest="40" />       
    </Grid>

    <!-- Row 1: Page Content -->
    <ScrollView Grid.Row="1">
        ...
    </ScrollView>
</Grid>

Code behind AlertDetailPage.xaml.cs

public AlertDetailPage()
{
    InitializeComponent();
    // Hide default NavigationBar
    NavigationPage.SetHasNavigationBar(this, false);
}

private async void OnBackButtonClicked(object sender, EventArgs e)
{
    await Navigation.PopAsync();
}

Also, you would need to handle the issue where opening an action sheet popup from the AlertDetailPage's three-dot menu was changing the bottom tab bar's FlowDirection from RTL to LTR.

Add this inside your DialogService.cs

// Navigate hierarchy to find presenting page (skips TabbedPage)
private Page GetPresentingPage()
{
    var mainPage = Application.Current?.MainPage;
    if (mainPage is FlyoutPage flyout)
    {
        if (flyout.Detail is NavigationPage detailNav)
        {
            // If Detail contains a TabbedPage, get the current tab's content
            if (detailNav.CurrentPage is TabbedPage tabbedPage)
            {
                var currentTab = tabbedPage.CurrentPage;
                // If current tab is a NavigationPage, get its current page
                if (currentTab is NavigationPage tabNav)
                {
                    return tabNav.CurrentPage; // AlertDetailPage
                }
                return currentTab;
            }
            return detailNav.CurrentPage;
        }
    }
    return mainPage;
}

public async Task<string> ShowChoices(string title, string cancel, 
                                       string destruction, params string[] buttons)
{
    var presentingPage = GetPresentingPage();
    // Store original FlowDirection values
    var originalPageFlow = presentingPage.FlowDirection;
    var originalParentFlow = FlowDirection.MatchParent;
    NavigationPage parentNav = null;
    if (presentingPage.Parent is NavigationPage nav)
    {
        parentNav = nav;
        originalParentFlow = nav.FlowDirection;
    }
    try
    {
        // Force LTR only on presenting page and its NavigationPage
        presentingPage.FlowDirection = FlowDirection.LeftToRight;
        if (parentNav != null)
        {
            parentNav.FlowDirection = FlowDirection.LeftToRight;
        }
        return await presentingPage.DisplayActionSheet(
            title, 
            cancel ?? "DialogCancel".Localized(), 
            destruction, 
            buttons);
    }
    finally
    {
        // Restore original FlowDirection values
        presentingPage.FlowDirection = originalPageFlow;
        if (parentNav != null)
        {
            parentNav.FlowDirection = originalParentFlow;
        }
    }
}

Was this answer helpful?

1 person found this answer helpful.

0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.