How do I set the gradient of a ProgressBar
in XAML to dynamic filling?
At the moment its like:
Code for both progress bars:
<ProgressBar.Foreground>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<CompositeTransform CenterY="0.5" CenterX="0.5" Rotation="270"/>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="Lime" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</ProgressBar.Foreground>
but I want to have the "end"color of the upper ProgressBar
in the green-yellowish color like directly below.
Means I want the progress bar full filled like the second bar and then "cut" the rest out (e.g. when I have 60% I want the 40% on the right not shown)
How do I do this properly?
Edit (found a solution):
After trying a couple of ways (drawing a rectangle with default color onto the bar etc) I figured out that I can modify the offset
of GradientStop
by code:
color_UL.Offset = 2.0 - ul_val / 100;
means I subtract the percentage that I want to display e.g. 30% (ul_val = 30
) the Offset is set to 170% (1.7) but the bar itself shows 30% with the smooth and right color gradient. If I have 100% on the bar it calculates 2.0 - 1.0
which is 1 (like normal, shown in Bar #2 in picture 1).
I know this sounds all confusing, so here the picture as I wanted it to be:
A second approach to achieving this layout is to set the background as the graded color and then use the foreground color as grey, remembering that your value of the progress bar needs to be
100-value
as you'll be setting the value for the gray area of the bar which starts at 100% (value = 0 OR no gray in the bar) and moves towards 0% (value = 100 OR entire bar is gray)
100% (value = 100 - %)
99% (value = 100 - %)
50% (value = 100 - %)
0% (value = 100 - %)
In your MainPage.xaml.cs (or where ever you need to call it)
var percentage = 75;
progressBar.Value = 100 - percentage;
In your MainPage.xaml
<ProgressBar x:Name="progressBar" HorizontalAlignment="Left" Height="80" Margin="-82,121,0,0" VerticalAlignment="Top" Width="270" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto"
Minimum="0" Maximum="100" Value="0" Foreground="Gray">
<ProgressBar.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<CompositeTransform CenterY="0.5" CenterX="0.5" Rotation="270"/>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="Lime" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</ProgressBar.Background>
<ProgressBar.RenderTransform>
<CompositeTransform Rotation="90"/>
</ProgressBar.RenderTransform>
</ProgressBar>
You might need to fiddle with the orientation of the progress bar so that it displays correctly, the above code is for a vertical bar which can be used for something like a fuel gauge.
My Solution:
After trying a couple of ways (drawing a rectangle with default color onto the bar etc) I figured out that I can modify the offset
of GradientStop
by code:
color_UL.Offset = 2.0 - ul_val / 100;
means I subtract the percentage that I want to display e.g. 30% (ul_val = 30
) the Offset is set to 170% (1.7) but the bar itself shows 30% with the smooth and right color gradient. If I have 100% on the bar it calculates 2.0 - 1.0
which is 1 (like normal, shown in Bar #2 in picture 1).
I know this sounds all confusing, so here the picture as I wanted it to be:
You can define in the XAML just the starting color (i.e. red(255,0,0) and calculate in your code the ending color performing a linear interpolation between the 100% color (i.e. LimeGreen(50,205,50). Binding ProgressColor (the color to calculate) in XAML:
<ProgressBar Value="{Binding Progress, Mode=OneWay}" Minimum="0" Maximum="100" >
<ProgressBar.Foreground>
<LinearGradientBrush EndPoint="0, 0.5" StartPoint="1, 0.5">
<GradientStop Color="{Binding ProgressColor, Mode=OneWay}" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</ProgressBar.Foreground>
Then somewhere else do your maths:
public string ProgressColor
{
get
{
int R = Convert.ToInt32(Math.Floor(255 - (255 - 50) * YourNeededPercentage));
int G = Convert.ToInt32(Math.Floor(205 * YourNeededPercentage));
int B = Convert.ToInt32(Math.Floor(50 * YourNeededPercentage));
string ProgressColor = String.Format("#{0:X2}{1:X2}{2:X2}", R, G, B);
return ProgressColor;
}
}