wpfprogress-barimultivalueconverter

WPF: Change Progress-Bar color with IMultiValueConverter


Ok so i have this properties in my View Model:

public double Progress
{
    get { return _progress; }
    set
    {
        _progress= value;
        OnPropertyChanged();
    }
}

public bool IsChecked
{
    get { return _isChecked; }
    set
    {
        _isChecked = value;
        OnPropertyChanged();
    }
}

And as you can see this implement INotifyPropertyChanged.

This is my Progress-Bar:

<ProgressBar Name="progressBarColumn"
             Minimum="0"
             Maximum="100"
             Value="{Binding Progress, UpdateSourceTrigger=PropertyChanged}" 
             Width="{Binding Path=Width, ElementName=ProgressCell}" 
             Style="{StaticResource CustomProgressBar2}"/>

And my Style:

<Style x:Key="CustomProgressBar2" TargetType="ProgressBar">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ProgressBar" >
                <Grid x:Name="Root">
                    <Border Name="PART_Track" 
                            CornerRadius="0" 
                            Background="Blue"
                            BorderBrush="Blue"
                            BorderThickness="1"/>
                    <Border Name="PART_Indicator" 
                            CornerRadius="0" 
                            Background="Gray" 
                            BorderBrush="Gray" 
                            BorderThickness="1" 
                            HorizontalAlignment="Left" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

So this works fine, my Progress-Bar color is Blue and fill with Gray color.

Now i want to add two more things and dont know when: 1. When my Progress-Bar reach the Value of 100 i want it Background become Green.

  1. When my Property called IsChecked is False i want that my Background become Red.

So until here i have this IMultiValueConverter:

public class ProgressToPropgressBarBackgroundConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            // Do my stuff
        }

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

The problem is that i dont know where to add my converter and how.

EDIT:

<Style x:Key="CustomProgressBar2" TargetType="ProgressBar">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ProgressBar" >
                <Grid x:Name="Root">
                    <Border Name="PART_Track" 
                            CornerRadius="0" 
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding Background}"
                            BorderThickness="1"/>
                    <Border Name="PART_Indicator" 
                            CornerRadius="0" 
                            Background="{TemplateBinding Foreground}" 
                            BorderBrush="{TemplateBinding Foreground}" 
                            BorderThickness="1" 
                            HorizontalAlignment="Left" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <DataTrigger Value="100" Binding="{Binding Path=Value, RelativeSource={RelativeSource AncestorType=ProgressBar}}">
            <Setter Property="Foreground" Value="DarkCyan"/>
        </DataTrigger>

        <DataTrigger Binding="{Binding IsChecked}" Value="true">
            <Setter Property="Background" Value="{DynamicResource ProgressBackgroundColor}" />
            <Setter Property="Foreground" Value="{DynamicResource ProgressBarFillColor}" />
        </DataTrigger>

        <DataTrigger Binding="{Binding IsChecked}" Value="false">
            <Setter Property="Background" Value="#55B3B3B6" />
        </DataTrigger>
    </Style.Triggers>
</Style>

Solution

  • You logic is simple enough you can avoid a converter and simply use triggers in your style:

    <Style.Triggers>
        <DataTrigger Binding=“{Binding Progress}” Value=“100”>
            <Setter Property=“Background” Value=“Green” />
        </DataTrigger>
        <DataTrigger Binding=“{Binding IsChecked}” Value=“True”>
            <Setter Property=“Background” Value=“Red” />
        </DataTrigger>
    </Style.Triggers>
    

    Then you need to update your control template to properly respect the control’s Background property. You can use TemplateBinding for this:

                    <Border Name="PART_Track" 
                            CornerRadius="0" 
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding Background}"
                            BorderThickness="1"/>
                    <Border Name="PART_Indicator" 
                            CornerRadius="0" 
                            Background="{TemplateBinding Foreground}" 
                            BorderBrush="{TemplateBinding Foreground}" 
                            BorderThickness="1" 
                            HorizontalAlignment="Left" />
    

    And if you want the same Blue and Gray default colors, add them to the style:

    <Setter Property=“Background” Value=“Blue”/>
    <Setter Property=“Foreground” Value=“Gray”/>