OXO
OXO

Reputation: 1098

Understanding Stacking in Grid

I do not understand stacking other layouts in a Grid regarding ZIndex:

<Grid RowDefinitions=“Auto”>
    <Image Grid.Row=“0” Source=…/>

    <ScrollView Grid.Row=“0”>
        <LinearGradientBrush>…
        <LinearGradientBrush>…
    </ScrollView>

    <ScrollView Grid.Row=“0”>
       <Grid>
       …
       </Grid>
    </ScrollView>
</Grid>

When I have 1 ScrollView in Row=0 then it is displayed correctly, on the bottom (in the background) my Image, on top of it the LinearGradientBrush.

But, when I add a 2nd ScrollView it shows like the LinearGradientBrush is destroyed and also the 2nd ScrollView is not displayed correctly on top of both. Same when Background of the 2nd ScrollView is set to Transparent.

What I want is a Background Image, on top of that a LinearGradientBrush and on top of that a very high ScrollView ranging even out of the Grid down area. It should be just like setting ZIndexes from 0 to 2 for these elements.

Even when I try setting ZIndexes it does not work.

What works ie setting the 2nd ScrollView to Row=1, but then I would need a negative Margin to move it from Row=1 position up to the Start or Row=0.

I could do this with negative margin, but am not sure how good it works with different Screen Sizes or when orientation is not Portrait but Landscape.

Any ideas or explanations for this stacking behavior?

========= Additional information regarding comments ============

Let's start from the very beginning with just my background image and right beside of it the LinearGradientBrush:

1) Just the Background Image

<Grid RowDefinitions="Auto">
    <Image x:Name="BackgroundImage" Grid.Row="0" Source="radiant_gradient.png" Aspect="AspectFill"/>
</Grid>

2) On top of it the LinearGradientBrush - both in Grid.Row="0"

<Grid RowDefinitions="Auto">

    <Image x:Name="BackgroundImage" Grid.Row="0" Source="radiant_gradient.png" Aspect="AspectFill"/>

    <ScrollView Grid.Row="0">
        <ScrollView.Background>
            <LinearGradientBrush EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0.1" />
                <GradientStop Color="White" Offset="1.0" />
            </LinearGradientBrush>
        </ScrollView.Background>
    </ScrollView>
    
</Grid>

enter image description here

3) 2nd ScrollView is so high that it should range outside the Grid - Height of ScrollView is set in OnSizeAllocated

protected override void OnSizeAllocated(double width, double height)
{
    ScrollView.Height = height * 1.5;
}
<Grid RowDefinitions="Auto">

    <Image x:Name="BackgroundImage" Grid.Row="0" Source="radiant_gradient.png" Aspect="AspectFill"/>

    <ScrollView Grid.Row="0">
        <ScrollView.Background>
            <LinearGradientBrush EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0.1" />
                <GradientStop Color="White" Offset="1.0" />
            </LinearGradientBrush>
        </ScrollView.Background>
    </ScrollView>


    <ScrollView x:Name="ScrollView" Grid.Row="0" BackgroundColor="Transparent" >
        <Grid RowDefinitions="Auto">
            <Frame Grid.Row="0" BorderColor="LightGray" Background="{StaticResource White}" Opacity="0.9" HeightRequest="65" 
                   HasShadow="False" CornerRadius="10" Padding="0">

                <Grid ColumnDefinitions="*, Auto" Margin="15, 15, 15, 15">
                    <Entry/>
                    <!--Save Button-->
                    <Button Grid.Column="1" Text="{loc:Translate SaveMealButton_Text}" Command="{Binding SaveMealCommand}" Clicked="Button_Clicked" HeightRequest="35" WidthRequest="100" FontAutoScalingEnabled="True" VerticalOptions="FillAndExpand" Padding="15, 7, 15, 10"/>
                </Grid>

            </Frame>
        </Grid>
    </ScrollView>
    
</Grid>

enter image description here

4) Height of 2nd ScrollView is not set to height * 1.5

Basically, this is how it should look like in the end. Well, Margin could be set so that it looks good, but anyway - position of the Frame is right.

Unfortunately, the Height of the ScrollView should range outside the Grid. When I change the Height of the Grid it also affects the Height of Row=0 and the LinearGradientBrush

enter image description here

5) RowDefinitions of Grid set to 2000

<Grid RowDefinitions="2000">

    <Image x:Name="BackgroundImage" Grid.Row="0" Source="radiant_gradient.png" Aspect="AspectFill"/>

    <ScrollView Grid.Row="0">
        <ScrollView.Background>
            <LinearGradientBrush EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0.1" />
                <GradientStop Color="White" Offset="1.0" />
            </LinearGradientBrush>
        </ScrollView.Background>
    </ScrollView>


    <ScrollView x:Name="ScrollView" Grid.Row="0" BackgroundColor="Transparent" >
        <Grid RowDefinitions="Auto">
            <Frame Grid.Row="0" BorderColor="LightGray" Background="{StaticResource White}" Opacity="0.9" HeightRequest="65" 
                   HasShadow="False" CornerRadius="10" Padding="0">

                <Grid ColumnDefinitions="*, Auto" Margin="15, 15, 15, 15">
                    <Entry/>
                    <!--Save Button-->
                    <Button Grid.Column="1" Text="{loc:Translate SaveMealButton_Text}" Command="{Binding SaveMealCommand}" Clicked="Button_Clicked" HeightRequest="35" WidthRequest="100" FontAutoScalingEnabled="True" VerticalOptions="FillAndExpand" Padding="15, 7, 15, 10"/>
                </Grid>

            </Frame>
        </Grid>
    </ScrollView>
    
</Grid>

enter image description here

=========== Additional info regarding use of BoxView ==================

As mentioned in the Comment why not use a BoxView. BoxView here has a strange behavior in this case and just draws a black box without LinearGradientBrush and without making my background image visible:

<!--Just the Background Image and the LinearGradient-->
<Grid Grid.Row="0" RowDefinitions="Auto">
    
    <Image x:Name="BackgroundImage" Grid.Row="0" Source="vegetables_with_salt_corn_cob.png" Aspect="AspectFill"/>

    <BoxView Grid.Row="0">
        <BoxView.Background>
            <LinearGradientBrush EndPoint="0,1">
                <GradientStop Color="Transparent" Offset="0.1" />
                <GradientStop Color="White" Offset="1.0" />
            </LinearGradientBrush>
        </BoxView.Background>
    </BoxView>
    
    <!--Frame 1:  Entry for Saved Meal Name and Save-Button-->
    <Frame Grid.Row="0" Style="{StaticResource FrameStyleView}" HeightRequest="65">

        <Grid ColumnDefinitions="*, Auto" Margin="15">
            <picker:CustomPickerControl Grid.Column="0" Text="{Binding SelectedMealName, Mode=TwoWay}" Placeholder="{loc:Translate CustomPickerControl_Placeholder}" BorderColor="{x:StaticResource Gray400}" Padding="0, 0, 25, 0" Margin="5, 0, 0, 0"/>

            <!--Save Button-->
            <Button Grid.Column="1" Text="{loc:Translate SaveMealButton_Text}" Command="{Binding SaveMealCommand}" Clicked="Button_Clicked" HeightRequest="35" WidthRequest="100" FontAutoScalingEnabled="True" VerticalOptions="FillAndExpand" Padding="15, 7, 15, 10"/>
        </Grid>

    </Frame>
    
</Grid>

enter image description here

Upvotes: 1

Views: 881

Answers (1)

ToolmakerSteve
ToolmakerSteve

Reputation: 21321

  • Don't attempt to have children extend outside the grid. Instead, have grid cover the entire area of its children.
  • To have grid children be different heights (but overlap), use Grid.RowSpan.
  • Setting BackgroundColor="Transparent" on ScrollView does not affect how ScrollView's children set their BackgroundColor. I'm not sure exactly what you wanted transparent, but try ALSO setting that transparency on children (and children of children, etc.), until what is underneath shows through. This can be more easily seen by first REMOVING all the children of ScrollView, to confirm that underneath is visible. Then gradually add children.
  • Should not need to set ScrollView's height in OnSizeAllocated. A row height of "*" uses all remaining height.
  • If this doesn't do what you need, then add a new section to question, describing what isn't right. Draw in red on a screenshot, to show what changes are desired.

Something like this:

<!-- Two rows -->
<Grid RowDefinitions="Auto,*">

    <Image x:Name="BackgroundImage" Grid.Row="0" ... />

    <ScrollView Grid.Row="0">
        <ScrollView.Background>
            <LinearGradientBrush EndPoint="0,1">
        ...

    <!-- RowSpan to cover both rows -->
    <ScrollView x:Name="ScrollView" Grid.Row="0" Grid.RowSpan="2" BackgroundColor="Transparent" >
        <Grid RowDefinitions="Auto" BackgroundColor="Transparent">
            <Frame ... >
        ...

  • Is there a reason to have LinearGradient be on a ScrollView? Don't use unless scrolling of that part is needed. See if it will work with BoxView or ContentView instead. (If not, maybe an empty Grid, or a VerticalStackLayout containing a BoxView or ContentView.)

Upvotes: 0

Related Questions