user3079834
user3079834

Reputation: 2214

c# XAML ProgressBar set gradient filling properly

How do I set the gradient of a ProgressBar in XAML to dynamic filling?

At the moment its like:

enter image description here

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:

ProgressBar with fitting gradient

Upvotes: 5

Views: 6243

Answers (3)

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;
        }
    }

Upvotes: 0

Gareth Andrews
Gareth Andrews

Reputation: 55

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)

enter image description here100% (value = 100 - %)

enter image description here99% (value = 100 - %)

enter image description here50% (value = 100 - %)

enter image description here0% (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.

Upvotes: 3

user3079834
user3079834

Reputation: 2214

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:

ProgressBar with fitting gradient

Upvotes: 1

Related Questions