1

I would like to know, how I could make the transition between two background colors more smooth. Is it possible to make some kind of fade transition?

I have created this little sample project to illustrate the behavior.

MainWindow.xaml

<Window x:Class="FadeTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Converter="clr-namespace:FadeTest" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <Converter:BackgroundPercentConverter x:Key="backgroundPercentConverter"/>
</Window.Resources>
<DockPanel>
    <Label Content="{Binding PercentComplete}" Height="100" Width="200" 
           DockPanel.Dock="Top" Foreground="White" FontSize="28" 
           Background="{Binding PercentComplete, Converter={StaticResource backgroundPercentConverter}}" 
           HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />
    <Button DockPanel.Dock="Bottom" Click="Button_Click" Width="100" Height="32">Click</Button>
</DockPanel>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MyClass {PercentComplete = 0};
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        ((MyClass) DataContext).PercentComplete++;
    }
}

MyClass.cs

class MyClass : INotifyPropertyChanged 
{
    private int _percentComplete;
    public int PercentComplete
    {
        get { return _percentComplete; }
        set
        {
            if (value >= 10)
                value = 0;
            _percentComplete = value;
            OnPropertyChanged("PercentComplete");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

BackgroundPercentConverter.cs

public class BackgroundPercentConverter : IValueConverter
{
    private static readonly SolidColorBrush[] MyColors = new[]
                                                             {
           new SolidColorBrush(Color.FromRgb(229, 29, 37)),
           new SolidColorBrush(Color.FromRgb(252, 52, 0)),
           new SolidColorBrush(Color.FromRgb(253, 81, 0)),
           new SolidColorBrush(Color.FromRgb(255, 101, 1)),
           new SolidColorBrush(Color.FromRgb(255, 133, 0)),
           new SolidColorBrush(Color.FromRgb(254, 175, 0)),
           new SolidColorBrush(Color.FromRgb(221, 182, 3)),
           new SolidColorBrush(Color.FromRgb(173, 216, 2)),
           new SolidColorBrush(Color.FromRgb(138, 191, 62)),
           new SolidColorBrush(Color.FromRgb(47, 154, 69))
                                                             };


    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if ((int)value < 0 || (int)value >= MyColors.Length)
            return MyColors[0];

        return MyColors[(int)value];
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
gulbaek
  • 2,481
  • 13
  • 44
  • 65
  • why don't you use controlled storyboard animation ? (I think it would save your life) – HichemSeeSharp Jul 29 '12 at 10:29
  • Gonna take a look, got any relevant links? – gulbaek Jul 29 '12 at 10:44
  • Either a StoryBoard or set some visual state with a Visual State Manager. You can do that interactively by using Expression Blend or by hand with the appropriate markup. http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/268ef5c9-4b72-4eef-a45c-1b20f14cb0f9/ – Colin Smith Jul 29 '12 at 10:44

1 Answers1

1

You could define a StoryBoard which has a ColorAnimation which defines a from and to colour i.e. the colours you want to interpolate smoothly between.

Your animation should target the Color property of a SolidColorBrush which can either be one that is defined as a Resource and is then referenced by your control (i.e. your Label uses {StaticResource xxxxxx} in the Background to refer to it, or your animation could target the Background in your Label directly IF the Background contains a Brush which is a SolidColorBrush (...normally that is the case...but that depends entirely on how the Template for the control is designed).

Then you would need to begin and pause the animation and seek to the position in the animation that corresponds to your percentage. E.g. you could set the Duration to 100 seconds, and then you could simply use your percentage value as the number of seconds in a TimeSpan. (Might have to set IsControllable=true).

You would start and pause the animation when the control is loaded, and then change the seek position in sync with your percentage change.

Note, it's probably a bad idea just having an animation running all the time, just to map a range value to a presentation colour, but it's another option to what you have.

Otherwise stick to your valueconverter and you could calculate the linear interpolation between the 2 colours yourself. See this link:

Here are some links related to the animation:

Community
  • 1
  • 1
Colin Smith
  • 12,375
  • 4
  • 39
  • 47