XAML gradient issue in UWP for some devices

C#XamlWin Universal-AppWindows 10-Universal

C# Problem Overview


I'm using Page as landing screen in my app. XAML looks like this:

<Grid x:Name="LayoutRoot">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="7*"/>
        </Grid.RowDefinitions>

        <Rectangle StrokeThickness="0" Fill="#FF79D2F4" Margin="0,0,0,-10" Grid.RowSpan="2"/>

        <Rectangle StrokeThickness="0" Fill="#FF1F8CC5" Margin="0,-10,0,0" Grid.Row="2" Grid.RowSpan="2"/>

        <Image Source="ms-appx:///Assets/ViewMedia/Banners/Banner_Light_Big.jpg" Grid.Row="1" Grid.RowSpan="2"/>

        <Rectangle StrokeThickness="0" Grid.Row="2" Grid.RowSpan="2">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Offset="0"/>
                    <GradientStop Color="#7F000000" Offset="1"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

    </Grid>

    <StackPanel MaxWidth="300" Margin="20,35"
                HorizontalAlignment="Stretch" VerticalAlignment="Bottom">

        <Button x:Name="LoginButton" x:Uid="LoginButton" Style="{StaticResource BrandButtonStyle}" Margin="0,5"
                Click="LoginButton_Click"/>

        <Button x:Name="RegisterButton" x:Uid="RegisterButton" Style="{StaticResource BrandButtonStyle}" Margin="0,5"
                Click="RegisterButton_Click"/>

    </StackPanel>

</Grid>

I've got 3 devices on which I'm running the app:

  • Microsoft Lumia 950 XL [M]
  • Custom build PC [PC]
  • Lenovo ThinkPad Tablet 2 [T]

When running the app this page renders well on M and PC but on T Gradient and two Buttons at the bottom are not rendered at all. I don't see them but I can press Buttons and their tap event handlers will strike. But if I comment Rectangle with gradient everything is fine on all devices.

This is how the app looks on T when using gradient. No buttons. And gradient is also not visible. With gradient

This is how the app looks on T without gradient. Buttons are in place. Without gradient

And this is how it should look running on PC. Buttons and gradient are visible. This is how it should look

I don't see any errors in output when running the app. I don't know why this happens only on specific devices. Maybe this is kind of known issue?

UPDATE 1

From users feedback, I can say that this bug hits only Atom-powered devices. But I'm not sure if this is 100% true for all Atom-powered devices.

UPDATE 2

I'd updated T with W10 from Insider Preview Fast Ring. The bug is in place. So this is not connected to OS builds.

UPDATE 3

Switching Buttons Style back to normal does not solve this. So Style is good, it's not the cause.

C# Solutions


Solution 1 - C#

Try removing the Grid.RowSpan="2" from the Rectangle (or add a RowDefinition), you have 4 rows (4 RowDefinition) but with the Rectangle having Grid.RowSpan=2 it adds up to 5 rows, so it might be causing you trouble.

EDIT: My bad, Rectangle actually spans over rows 2 and 3 (Grid.Row="2"), so it's ok.

Since you're just stacking <StackPanel> over <Grid> (with nothing fancy), you could try to replace the root layout <Grid x:Name="LayoutRoot"> with <Canvas x:Name="LayoutRoot"> and see if that makes a difference.

Solution 2 - C#

I've come across similar issues, and went for a different and more portable approach.

I made a gradient image of height 1 (to save space), and sufficient pixels in width to give the proper gradient resolution. Added an image and stretched it. Quite a bit faster and offloads the renderling pipeline as well.

And it works just as well in Xamarin.Forms.

Solution 3 - C#

The fact that the rectangle has a gradient in it is a probably a "red herring".

Focus first on why the buttons don't appear at all. Once you solve that, it should be easy to add the gradient.

There are two likely reasons:

  1. Adding the rectangle pushes the buttons down offscreen.

or 2. The renderer "choked" on the gradient, and didn't render anything else after it encountered it.

IMHO, #1 is more likely. I say that because I notice your overlaid StackLayout has VerticalAlignment="Bottom". So if the layout engine has (mistakenly?) decided that the single cell in the outermost grid is much taller than the screen, then two things will happen: the gradient will be stretched very far vertically (so appears not to change), and the buttons will be pushed off the bottom of the screen.

#2 would be a renderer bug involving gradient (but I doubt that will be the case).


back to #1:

What is the actual pixel height of "Banner_Light_Big.jpg"? Consider making a smaller version for the device giving you trouble [picking a version based on device height in inches or in pixels, not sure which applies here]. If you remove the banner completely, does the problem go away? If so, but you don't want to shrink it, you might need to override layout (measure?) method and do your own calculation.

Alternatively, change the two "Auto" heights to "NN*" or "NN" (NN = any specific number): anything with no "Auto"s will almost surely eliminate the problem.

If the resulting "non-Auto" layout isn't exactly what you want, at least it will give you a working starting point, from which to try slightly different variations on how to nest these elements, to get the desired spacing.

Solution 4 - C#

Try adding the color attribute and value for the first Gradient stop as well. Maybe since only a single color is specified, it takes the same color and applies throught the button.

<Rectangle.Fill>
      <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Offset="0"/> // add color attribute here
            <GradientStop Color="#7F000000" Offset="1"/>
      </LinearGradientBrush>
</Rectangle.Fill>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkhamitimurView Question on Stackoverflow
Solution 1 - C#Yoav AharoniView Answer on Stackoverflow
Solution 2 - C#RobinView Answer on Stackoverflow
Solution 3 - C#ToolmakerSteveView Answer on Stackoverflow
Solution 4 - C#GowshikView Answer on Stackoverflow