.netxamlmaui

Handling depth between elements inside an AbsoluteLayout in MAUI


I have a page named CameraPage containing an AbsoluteLayout that has multiple children, and my problem is that the biggest element that fills the layout is always in front of everything else.

Here is the page with the Frame in front and the AbsoluteLayout highlighted:Screenshot of CameraPage with the Frame in front and the AbsoluteLayout higlighted in red And here is what it looks like when the frame is hidden (I forced my status button in green to be shown for clarity):Screenshot of CameraPage with the Frame hidden and the AbsoluteLayout higlighted in red The code that is relevant for the question is :

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="DermAtoZ.Views.Pages.CameraPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:converters="clr-namespace:DermAtoZ.Views.Converters"
    xmlns:custom="clr-namespace:DermAtoZ.Views.Custom"
    xmlns:local="clr-namespace:DermAtoZ.MarkupExtentions"
    xmlns:p="clr-namespace:DermAtoZ.Views.Pages"
    xmlns:vm="clr-namespace:DermAtoZ.ViewModels"
    Title="{local:Translate AppName}"
    x:DataType="vm:CameraViewModel">
    <Shell.TitleView>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="180" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Image
                Grid.Row="0"
                Grid.Column="0"
                Margin="0"
                HeightRequest="50"
                HorizontalOptions="CenterAndExpand"
                MinimumHeightRequest="50"
                MinimumWidthRequest="180"
                Source="dermatoz.png"
                WidthRequest="180" />
            <Label
                Grid.Row="0"
                Grid.Column="1"
                FontSize="Small"
                HorizontalTextAlignment="Center"
                Text="Powered by Pixience"
                TextColor="White"
                VerticalOptions="Center"
                VerticalTextAlignment="Center" />
        </Grid>
    </Shell.TitleView>
    <ContentPage.ToolbarItems>
        <ToolbarItem
            Clicked="OpenConfigurationPage_Clicked"
            Order="Secondary"
            Priority="0"
            Text="{local:Translate Configuration}" />
        <ToolbarItem
            Clicked="PickPhoto_ClickedAsync"
            Order="Secondary"
            Priority="0"
            Text="{local:Translate Gallery}" />
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <Grid RowSpacing="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="16*" />
                <RowDefinition Height="3*" />
                <RowDefinition Height="5*" />
            </Grid.RowDefinitions>
            <AbsoluteLayout>
                <!--  Status button  -->
                <ImageButton
                    x:Name="StatusButton"
                    AbsoluteLayout.LayoutBounds="0.05, 0.05"
                    AbsoluteLayout.LayoutFlags="PositionProportional"
                    BackgroundColor="{StaticResource GreenColor}"
                    BorderColor="White"
                    BorderWidth="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=8}"
                    Clicked="Resend_Clicked"
                    HeightRequest="{Binding Height, Source={RelativeSource AncestorType={x:Type AbsoluteLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=10}"
                    IsVisible="False"
                    Source="confirm.png">
                    <ImageButton.Style>
                        <Style BasedOn="{StaticResource ButtonImageRound}" TargetType="ImageButton">
                            <Style.Triggers>
                                <DataTrigger
                                    Binding="{Binding TransferStatus}"
                                    TargetType="ImageButton"
                                    Value="False">
                                    <Setter Property="Source" Value="repeat.png" />
                                    <Setter Property="IsVisible" Value="True" />
                                    <Setter Property="BackgroundColor" Value="{StaticResource RedColor}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ImageButton.Style>
                </ImageButton>

                <!--  Zone label  -->
                <Button
                    Margin="0"
                    Padding="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=12}"
                    AbsoluteLayout.LayoutBounds="1, 0.7, AutoSize, AutoSize"
                    AbsoluteLayout.LayoutFlags="PositionProportional"
                    BackgroundColor="{StaticResource PrimaryLightColor}"
                    BorderColor="White"
                    BorderWidth="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=8}"
                    Clicked="OpenBodyPage_Clicked"
                    FontSize="Medium"
                    IsVisible="{Binding CaptureMode, Converter={StaticResource InvertBoolConverter}}"
                    Rotation="90"
                    Text=" Zone "
                    TextColor="White"
                    TextTransform="Uppercase"
                    TranslationX="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=40}" />

                <!--  Background image  -->
                <Frame
                    Margin="0"
                    Padding="0"
                    AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                    AbsoluteLayout.LayoutFlags="All"
                    BackgroundColor="Black"
                    CornerRadius="0"
                    IsClippedToBounds="True"
                    IsVisible="False">
                    <custom:PinchToZoomContainer VerticalOptions="Center">
                        <custom:PinchToZoomContainer.Content>
                            <Image x:Name="TakenPictureImage" Aspect="AspectFit" />
                        </custom:PinchToZoomContainer.Content>
                    </custom:PinchToZoomContainer>

                </Frame>
            </AbsoluteLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>

So far I have tried using ZIndex to order the elements but that was inconclusive and reordering the elements by putting the Frame first or last but that didn't work either.

Here is the full code in case more context is needed:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="DermAtoZ.Views.Pages.CameraPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:converters="clr-namespace:DermAtoZ.Views.Converters"
    xmlns:custom="clr-namespace:DermAtoZ.Views.Custom"
    xmlns:local="clr-namespace:DermAtoZ.MarkupExtentions"
    xmlns:p="clr-namespace:DermAtoZ.Views.Pages"
    xmlns:vm="clr-namespace:DermAtoZ.ViewModels"
    Title="{local:Translate AppName}"
    x:DataType="vm:CameraViewModel">
    <Shell.TitleView>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="180" />
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Image
                Grid.Row="0"
                Grid.Column="0"
                Margin="0"
                HeightRequest="50"
                HorizontalOptions="CenterAndExpand"
                MinimumHeightRequest="50"
                MinimumWidthRequest="180"
                Source="dermatoz.png"
                WidthRequest="180" />
            <Label
                Grid.Row="0"
                Grid.Column="1"
                FontSize="Small"
                HorizontalTextAlignment="Center"
                Text="Powered by Pixience"
                TextColor="White"
                VerticalOptions="Center"
                VerticalTextAlignment="Center" />
        </Grid>
    </Shell.TitleView>
    <ContentPage.ToolbarItems>
        <ToolbarItem
            Clicked="OpenConfigurationPage_Clicked"
            Order="Secondary"
            Priority="0"
            Text="{local:Translate Configuration}" />
        <ToolbarItem
            Clicked="PickPhoto_ClickedAsync"
            Order="Secondary"
            Priority="0"
            Text="{local:Translate Gallery}" />
    </ContentPage.ToolbarItems>
    <ContentPage.Content>
        <Grid RowSpacing="0">
            <Grid.RowDefinitions>
                <RowDefinition Height="16*" />
                <RowDefinition Height="3*" />
                <RowDefinition Height="5*" />
            </Grid.RowDefinitions>
            <AbsoluteLayout>
                <!--  Status button  -->
                <ImageButton
                    x:Name="StatusButton"
                    AbsoluteLayout.LayoutBounds="0.05, 0.05"
                    AbsoluteLayout.LayoutFlags="PositionProportional"
                    BackgroundColor="{StaticResource GreenColor}"
                    BorderColor="White"
                    BorderWidth="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=8}"
                    Clicked="Resend_Clicked"
                    HeightRequest="{Binding Height, Source={RelativeSource AncestorType={x:Type AbsoluteLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=10}"
                    IsVisible="False"
                    Source="confirm.png">
                    <ImageButton.Style>
                        <Style BasedOn="{StaticResource ButtonImageRound}" TargetType="ImageButton">
                            <Style.Triggers>
                                <DataTrigger
                                    Binding="{Binding TransferStatus}"
                                    TargetType="ImageButton"
                                    Value="False">
                                    <Setter Property="Source" Value="repeat.png" />
                                    <Setter Property="IsVisible" Value="True" />
                                    <Setter Property="BackgroundColor" Value="{StaticResource RedColor}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ImageButton.Style>
                </ImageButton>

                <!--  Zone label  -->
                <Button
                    Margin="0"
                    Padding="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=12}"
                    AbsoluteLayout.LayoutBounds="1, 0.7, AutoSize, AutoSize"
                    AbsoluteLayout.LayoutFlags="PositionProportional"
                    BackgroundColor="{StaticResource PrimaryLightColor}"
                    BorderColor="White"
                    BorderWidth="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=8}"
                    Clicked="OpenBodyPage_Clicked"
                    FontSize="Medium"
                    IsVisible="{Binding CaptureMode, Converter={StaticResource InvertBoolConverter}}"
                    Rotation="90"
                    Text=" Zone "
                    TextColor="White"
                    TextTransform="Uppercase"
                    TranslationX="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=40}" />

                <!--  Background image  -->
                <Frame
                    Margin="0"
                    Padding="0"
                    AbsoluteLayout.LayoutBounds="0, 0, 1, 1"
                    AbsoluteLayout.LayoutFlags="All"
                    BackgroundColor="Black"
                    CornerRadius="0"
                    IsClippedToBounds="True"
                    IsVisible="False">
                    <custom:PinchToZoomContainer VerticalOptions="Center">
                        <custom:PinchToZoomContainer.Content>
                            <Image x:Name="TakenPictureImage" Aspect="AspectFit" />
                        </custom:PinchToZoomContainer.Content>
                    </custom:PinchToZoomContainer>

                </Frame>
            </AbsoluteLayout>
            <!--  Bottom menu  -->
            <FlexLayout
                Grid.Row="1"
                AlignContent="Center"
                AlignItems="Center"
                BackgroundColor="{StaticResource PrimaryDarkColor}"
                Direction="Row"
                JustifyContent="SpaceAround">

                <!--  First Label with Responsive Font Size  -->
                <Label
                    FontSize="{Binding Width, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=5}"
                    HorizontalTextAlignment="Center"
                    Text="{local:Translate Clinical}"
                    TextColor="White" />

                <!--  Switch element  -->
                <Switch
                    HeightRequest="{Binding Height, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=45}"
                    IsToggled="{Binding CaptureMode, Mode=TwoWay}"
                    WidthRequest="{Binding Width, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=15}" />

                <!--  Second Label with Responsive Font Size  -->
                <Label
                    FontSize="{Binding Width, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=5}"
                    HorizontalTextAlignment="Center"
                    Text="{local:Translate Dermoscopy}"
                    TextColor="White" />

                <!--  Custom Button with Responsive Sizing  -->
                <custom:LabelButton
                    x:Name="MultiButton"
                    Clicked="MultiButton_Clicked"
                    HorizontalOptions="Center"
                    IsEnabled="{Binding CaptureMode, Mode=OneWay}"
                    Text="x1"
                    WidthRequest="{Binding Width, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=15}">
                    <custom:LabelButton.Style>
                        <Style BasedOn="{StaticResource ButtonLabel}" TargetType="custom:LabelButton">
                            <Style.Triggers>
                                <DataTrigger
                                    Binding="{Binding DermMode}"
                                    TargetType="custom:LabelButton"
                                    Value="True">
                                    <Setter Property="Text" Value="x3" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </custom:LabelButton.Style>
                </custom:LabelButton>
            </FlexLayout>
            <FlexLayout
                Grid.Row="2"
                AlignItems="Center"
                BackgroundColor="{StaticResource SecondaryDarkColor}"
                Direction="Row"
                JustifyContent="SpaceEvenly">
                <ImageButton
                    x:Name="MainButton"
                    Padding="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=25}"
                    Clicked="MainButton_Clicked"
                    HeightRequest="{Binding Height, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=70}"
                    Source="clinical.png">
                    <ImageButton.Style>
                        <Style BasedOn="{StaticResource Key=ButtonImageRound}" TargetType="ImageButton">
                            <Style.Triggers>
                                <DataTrigger
                                    Binding="{Binding CaptureMode}"
                                    TargetType="ImageButton"
                                    Value="True">
                                    <Setter Property="Source" Value="dermoscopy.png" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ImageButton.Style>
                </ImageButton>
                <Button
                    Padding="{Binding Height, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=10}"
                    Command="{Binding AButtonCommand}"
                    Style="{StaticResource ButtonRound}"
                    Text="A" />
                <Button
                    Padding="{Binding Height, Source={RelativeSource AncestorType={x:Type FlexLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=10}"
                    Command="{Binding BButtonCommand}"
                    Style="{StaticResource ButtonRound}"
                    Text="B" />
            </FlexLayout>
        </Grid>
    </ContentPage.Content>
</ContentPage>

Thank you for reading this far !


Solution

  • I was able to fix this problem in both places I encountered it by setting the HasShadow Frame property to false. Once that was done I put the frame first in my xaml and this time it worked. Working xaml:

    <?xml version="1.0" encoding="utf-8" ?>
    <ContentPage
        x:Class="DermAtoZ.Views.Pages.CameraPage"
        xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:converters="clr-namespace:DermAtoZ.Views.Converters"
        xmlns:custom="clr-namespace:DermAtoZ.Views.Custom"
        xmlns:local="clr-namespace:DermAtoZ.MarkupExtentions"
        xmlns:p="clr-namespace:DermAtoZ.Views.Pages"
        xmlns:vm="clr-namespace:DermAtoZ.ViewModels"
        Title="{local:Translate AppName}"
        x:DataType="vm:CameraViewModel">
        <Shell.TitleView>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="180" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>
                <Image
                    Grid.Row="0"
                    Grid.Column="0"
                    Margin="0"
                    HeightRequest="50"
                    HorizontalOptions="CenterAndExpand"
                    MinimumHeightRequest="50"
                    MinimumWidthRequest="180"
                    Source="dermatoz.png"
                    WidthRequest="180" />
                <Label
                    Grid.Row="0"
                    Grid.Column="1"
                    FontSize="Small"
                    HorizontalTextAlignment="Center"
                    Text="Powered by Pixience"
                    TextColor="White"
                    VerticalOptions="Center"
                    VerticalTextAlignment="Center" />
            </Grid>
        </Shell.TitleView>
        <ContentPage.ToolbarItems>
            <ToolbarItem
                Clicked="ConfigurationPageButton_Clicked"
                Order="Secondary"
                Priority="0"
                Text="{local:Translate Configuration}" />
            <ToolbarItem
                Clicked="GalleryButton_Clicked"
                Order="Secondary"
                Priority="0"
                Text="{local:Translate Gallery}" />
        </ContentPage.ToolbarItems>
        <ContentPage.Content>
            <Grid RowSpacing="0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="16*" />
                    <RowDefinition Height="3*" />
                    <RowDefinition Height="5*" />
                </Grid.RowDefinitions>
                <AbsoluteLayout>
                    <!--  Background image  -->
                    <Frame
                        Margin="0"
                        Padding="0"
                        AbsoluteLayout.LayoutBounds="0, 0,1,1"
                        AbsoluteLayout.LayoutFlags="All"
                        BackgroundColor="Black"
                        CornerRadius="0"
                        HasShadow="False"
                        IsClippedToBounds="True">
                        <custom:PinchToZoomContainer VerticalOptions="Center">
                            <custom:PinchToZoomContainer.Content>
                                <Image x:Name="TakenPictureImage" Aspect="AspectFit" />
                            </custom:PinchToZoomContainer.Content>
                        </custom:PinchToZoomContainer>
                    </Frame>
                    <!--  Status button  -->
                    <ImageButton
                        x:Name="StatusButton"
                        AbsoluteLayout.LayoutBounds="0.05, 0.05"
                        AbsoluteLayout.LayoutFlags="PositionProportional"
                        BackgroundColor="{StaticResource GreenColor}"
                        BorderColor="White"
                        BorderWidth="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=8}"
                        Clicked="StatusButton_Clicked"
                        HeightRequest="{Binding Height, Source={RelativeSource AncestorType={x:Type AbsoluteLayout}}, Converter={StaticResource PercentageConverter}, ConverterParameter=10}"
                        IsVisible="{Binding TransferStatus, Converter={StaticResource InvertBoolConverter}}"
                        Source="confirm.png"
                        TranslationX="30"
                        TranslationY="30">
                        <ImageButton.Style>
                            <Style BasedOn="{StaticResource ButtonImageRound}" TargetType="ImageButton">
                                <Style.Triggers>
                                    <DataTrigger
                                        Binding="{Binding TransferStatus}"
                                        TargetType="ImageButton"
                                        Value="False">
                                        <Setter Property="Source" Value="repeat.png" />
                                        <Setter Property="BackgroundColor" Value="{StaticResource RedColor}" />
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </ImageButton.Style>
                    </ImageButton>
    
                    <!--  Zone label  -->
                    <Button
                        Margin="0"
                        Padding="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=12}"
                        AbsoluteLayout.LayoutBounds="1, 0.7, AutoSize, AutoSize"
                        AbsoluteLayout.LayoutFlags="PositionProportional"
                        BackgroundColor="{StaticResource PrimaryLightColor}"
                        BorderColor="White"
                        BorderWidth="{Binding Height, Source={RelativeSource Self}, Converter={StaticResource PercentageConverter}, ConverterParameter=8}"
                        Clicked="BodyPageButton_Clicked"
                        FontSize="Medium"
                        HeightRequest="100"
                        Rotation="90"
                        Text=" Zone "
                        TextColor="White"
                        TextTransform="Uppercase"
                        WidthRequest="100" />
                </AbsoluteLayout>
    

    Still, this is only a fix and not really a solution, because it works but I don't know what causes the problem in the first place.