Evorlor
Evorlor

Reputation: 7553

WPF Binding TextBlock to ProgressBar with Percentage

I have a ProgressBar which has a maximum of 10,000 (not 100). I want the binded TextBox to show the percentage of the current Value, not the Value itself. Is it possible to do this in the .xaml code?

The following shows the current Value of my ProgressBar. I want it to show the Value / Maximum.

        <ProgressBar x:Name="calculationProgressBar" />
        <TextBlock x:Name="calculationProgressText" Text="{Binding ElementName=calculationProgressBar, Path=Value, StringFormat={}{0:0}%}" />

Upvotes: 2

Views: 5502

Answers (2)

pushpraj
pushpraj

Reputation: 13669

Since manipulations are not possible in XAML so converters is a approach for the same

I tried to write a simple code for you, using string format for percent notice StringFormat={}{0:P0}

XAML example

<StackPanel>
    <StackPanel.Resources>
        <l:ScaleConverter x:Key="ScaleConverter"/>
    </StackPanel.Resources>
    <Slider x:Name="calculationSource" Maximum="10000"/>
    <TextBlock Text="{Binding ElementName=calculationSource, 
                              Path=Value, StringFormat={}{0:P0}, 
                              Converter={StaticResource ScaleConverter}, 
                              ConverterParameter=10000}" />
</StackPanel>

I used slider instead of progressbar for easy demo, you can use any source

specify the max value in converter parameter

and P0 in string format means percentage format with 0 precision eg 0%, you can choose to make it P1 for 1 decimal and so on eg 0.0%

converter class

class ScaleConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return System.Convert.ToDouble(value) / System.Convert.ToDouble(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

converter is pretty simple, divide the value by the defined scale.

I hope you'll find it useful for your issue

Extras

additionally if you prefer to define the max range at a single location you can use resources for the same

<StackPanel>
    <StackPanel.Resources>
        <l:ScaleConverter x:Key="ScaleConverter"/>
        <sys:Double x:Key="maxRange">10000</sys:Double>
    </StackPanel.Resources>
    <Slider x:Name="calculationSource" Maximum="{StaticResource maxRange}"/>
    <TextBlock Text="{Binding ElementName=calculationSource, 
               Path=Value, StringFormat={}{0:P0}, 
               Converter={StaticResource ScaleConverter}, 
               ConverterParameter={StaticResource maxRange}}" />
</StackPanel>

Upvotes: 1

sa_ddam213
sa_ddam213

Reputation: 43596

You could setup a simple IMultiValueConverter and pass in the ProgressBars Value and Maximum properties

Example:

Converter

public class ValueToPercentConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        double value = System.Convert.ToDouble(values[0]);
        double maximum = System.Convert.ToDouble(values[1]);
        return (value / maximum) * 100;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Xaml:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="100" Width="100">
    <Window.Resources>
        <local:ValueToPercentConverter x:Key="ValueToPercentConverter" />
    </Window.Resources>
    <StackPanel>
        <ProgressBar x:Name="calculationProgressBar" Maximum="10000" Value="2566" Height="40"/>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding Converter="{StaticResource ValueToPercentConverter}" StringFormat="{}{0}">
                    <Binding ElementName="calculationProgressBar" Path="Value"/>
                    <Binding ElementName="calculationProgressBar" Path="Maximum"/>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </StackPanel>
</Window>

Result: enter image description here

Upvotes: 3

Related Questions