XAML gradient issue in UWP for some devices - c#

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.
This is how the app looks on T without gradient. Buttons are in place.
And this is how it should look running on PC. Buttons and gradient are visible.
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.

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.

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.

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:
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.

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>

Related

Drop shadow effect in Windows Phone 8.1 Runtime?

I'm looking for a way to add a Drop Shadow Effect to the multiple kind of elements in my Windows Phone 8.1 Runtime (not Silverlight!) application. The main problem is that.. there's no offical API for it. The main problem is that I need to mimic this effect not only to the basic shapes (like rectangle or a line), but also a path, like here:
Picture is borrowed from this question: path-with-broken-shadow-effect - I hope the owner won't mind ;) Now, he has achieved this effect because it was done in WPF. I'm working on a Universal App (so WinRT), and there's no Effects extension.
I've searched the web multiple times, and found some kind of workarounds, but they all miss something. For example this one:
http://www.silverlightshow.net/items/Simple-Xaml-Drop-Shadows-in-Silverlight-2.aspx <- I can't work on Canvas, the content has to be a Grid.
Do you any idea how can I achieve satisfying results on faking Drop Shadow Effect in Windows Phone 8.1 Runtime?
Apply a RenderTransform to the shadow shape. Set the scale to make it bigger:
<Grid Style="{StaticResource LayoutRootStyle}" Background="#FF803535" >
<Rectangle Width="100" Height="100" Opacity="0.3" RenderTransformOrigin="0,0" StrokeThickness="16" StrokeDashCap="Round" StrokeEndLineCap="Round" StrokeLineJoin="Round" StrokeStartLineCap="Round" Stroke="Black" >
<Rectangle.RenderTransform>
<CompositeTransform ScaleX="1.07" ScaleY="1.07" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Width="100" Height="100" Fill="Blue"></Rectangle>
</Grid>

WPF XAML clipping ellipse on canvas when using TranslateTransform

When I run this code in WPF it gives me 1/4 of a circle. When removing the ClipToBounds tag, i get my whole circle.
1. Why is it clipping before rendering?
2. How to i fix that, while keeping clipping?
<Canvas ClipToBounds="True">
<Ellipse Canvas.Left="-10"
Canvas.Top="-10"
Width="20"
Height="20"
Fill="LightSeaGreen"/>
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="4.8"
ScaleY="4.8"
CenterX="0"
CenterY="0"/>
<TranslateTransform X="48"
Y="48"/>
</TransformGroup>
</Canvas.RenderTransform>
</Canvas>
Why is it clipping before rendering?
It's not.
As you can see from here:
Your Ellipse is rendered perfectly. The ClipToBounds="True" is what ruins is as you can see from your Canvas:
How to i fix that, while keeping clipping?
This is quite a broad question. Your problem comes from the fact you are putting your Ellipse outside the Canvas (Canvas.Left="-10" Canvas.Top="-10") and then you clip it. Explain what is your goal and I can try to help you out.
This behaviour is by design. The authors of the textbook (Computer Graphics: Principles and Practice - Third Edition) have confusingly introduced ClipToBounds in a way that makes it seem like it is a part of the examples that follow in the book. In fact, they are not using ClipToBounds="True". You can verify that by downloading their lab package from http://sklardevelopment.com/graftext/ChapWPF2D/ .
To illustrate, here is the actual source code for one of their examples:
<Canvas
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="ClockCanvas" >
<Ellipse
Width="20.0" Height="20.0"
Canvas.Left="-10.0" Canvas.Top="-10.0"
Fill="lightgray"/>
</Canvas>
Note that there is no ClipToBounds="True" on the canvas.

Is it possible to set a border to overlay (like in photoshop)

I am having a quite exotic question:
I am currently working on a "borderless" WPF Application. I successfully removed the standard windows window controls and added my own. Now I wanted to add a border to the programm. But I don't want the border to have specifc color, I want it to be in some kind of overlay mode like when you set a layer in photoshop to overlay. You can see what I mean in an example:
I really want it to look like on the left. But unfortunately I really have no idea how.
Basically what the overlay does is that it takes the background color and it makes it a bit darker.
Do you have any suggestions what I could do?
Edit: Here is a better picture of the effect
Photoshop Mookup2 http://img.xrmb2.net/images/243147.png
Edit2 : So, as a short explanation because it may not be as clear as I have hoped: I am not talking about a semi-transparency. I know how to do that. The right box in both images uses that. It has a black-semitransparent look. While on the left I set the border to "overlay" mode. As you can see it gets darker but also a bit stronger in color.
How about using the Transparent brush?:
<Border BorderBrush="Transparent" BorderThickness="5">
...
</Border>
UPDATE >>>
Oh, hold on... I see what you want... try this instead with a semi opaque `brush:
<Border BorderBrush="3F000000" BorderThickness="5">
...
</Border>
You can adjust the darkness of the Border, by changing the first two hexadecimal characters: 3F.
UPDATE >>>
I believe that this is the correct solution. As I said last:
You can adjust the darkness of the Border, by changing the first two hexadecimal characters
So just try different values until you get the right balance of opacity. Start with hardly visible black and then increase the opacity until you get it right:
<Border BorderBrush="08000000" BorderThickness="5">
...
</Border>
...
<Border BorderBrush="0F000000" BorderThickness="5">
...
</Border>
...
<Border BorderBrush="1F000000" BorderThickness="5">
...
</Border>
...
<Border BorderBrush="2F000000" BorderThickness="5">
...
</Border>
If none of these values look quite right still, then use a semi-opaque white instead:
<Border BorderBrush="2FFFFFFF" BorderThickness="5">
...
</Border>

WPF-same arc segment to consist of 2 different colors

Requirement: i have to come with a voltmeter user control.
The following code draws a arc, consisting of voltmeter ticks and values.
<Path Name="Pth" Stroke="DarkGray" StrokeThickness="2" Width="Auto" Height="48" Canvas.Top="12">
<Path.Data>
<PathGeometry >
<PathFigure StartPoint="35,28">
<ArcSegment IsLargeArc="False"
Size="23,75"
Point="200,28"
SweepDirection="Clockwise"
RotationAngle="90"/>
</PathFigure>
</PathGeometry>
</Path.Data>
As one one can see above, the pen used is stroke=dark gray. i am not talking about Fill property.
A section of the arc ,however, has to be rendered in blue(as alarm value) in response to user specified range.Any section of the arc .
The big picture is the predominant section of arc is rendered by gray pen and the alarm section is blue.
The problem as one can see above , we can assign the pen only to Path(not the arcsegment or geometry or pathfigure) and the path can use only one pen at a time .
A gradient brush won't work here as colors blend in.Here the two sections of the arc has to be clearly distinct by color from each other.
if i use two paths dividing the arc into 2arcsegments , i have to take of the various existing calculations ,which depends on the path geometry's fraction values.
what's the best approach for my case? any suggestions guys?
Taken from here:
One idea could be using a gradient brush with no spacing between the color blocks.
For example:
<Rectangle Width="200" Height="50">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Red" Offset="0.500"/>
<GradientStop Color="Lime" Offset="0.500"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
Would result into something such as:
Although I'm afraid that you might have trouble finding the correct offset for it, in case it should be calculated dynamically.
EDIT: could you show us how the arc would approximately look like?

How do I get a ScrollViewer with a Rectangle inside to stop scrolling when it reaches the end of the rectangle?

I have created a Rectangle inside of a ScrollViewer like this
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Center" Width="728" Canvas.Top="20" d:LayoutOverrides="HorizontalMargin" >
<Rectangle x:Name="musicBG" Fill="#FF0692FD"/>
</ScrollViewer>
During the use of the app, the size of MusicBg changes, sometimes to something around 3,000 pixels width.
musicBG.Width = _songLength*PixelsPerSecond
However, while scrolling the scrollViewer, it allows me to scroll the rectangle all the way off the screen.
For example this line of code gives me the following values when I have moved the rectangle as far as I want to move it.
if (songScrollViewer.HorizontalOffset > songScrollViewer.ScrollableWidth)
HorizontalOffset has a value of ~1200 and ScrollableWidth has a value of about ~2900.
How can I get this to be done properly so that the rectangle is not scrolled completely off the screen?
I would expect a HorizontalOffset of about 1200 to only push the rectangle about halfway through to it's destination, and not make it start going off screen.
ANSWER:
After much frustration, I was able to solve this problem by using Canvas instead of Border or Rectangle.
I'll award points if anyone can explain why this problem happened, and if there is a less processor intensive control that would work better than canvas.
Edit: Screen shots:
Bad Code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Border x:Name="musicBG" Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</ScrollViewer>
Image of bad scroll with bad code:
Good working code:
<ScrollViewer ManipulationMode="Control" x:Name="songScrollViewer" Width="720" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled" Height="270" VerticalAlignment="Top" Canvas.Top="20" HorizontalAlignment="Left" >
<Canvas x:Name="musicBG" Background ="#FF0692FD" Height="270" >
<Border Background="#FF0692FD" VerticalAlignment="Top" HorizontalAlignment="Left" Height="270" />
</Canvas>
</ScrollViewer>
Good Scroll: Notice it says 170 seconds on the bottom right instead of the smaller number of 118 seconds in the bad scroll.
I believe your right, wp7 won't render shapes that are bigger then 2048 pixels. So the reason it's scrolling of the page is because it's treating it as if it were bigger then 2048 but you can only see up to a width of 2048px and its just scrolling over to the "ghost" part of the rectangle.
I'm not sure if you can override this but the best solution I could come up with (without overriding) is by splitting up your rectangle into chucks that are smaller then 2000 (just to be safe) and then displaying them seamlessly in a horizontal stack panel inside the scroll viewer. The problem with this is that depending on how you've coded it, this solution might be hard to implement; but you might just be able to split it in your ViewModel when displaying it and your logic would only see it as one big chunk.

Categories

Resources