File: Microsoft\Windows\Themes\ProgressBarHighlightConverter.cs
Project: wpf\src\Themes\Aero\PresentationFramework.Aero.csproj (PresentationFramework.Aero)
//---------------------------------------------------------------------------
//
// Copyright (C) by Microsoft Corporation.  All rights reserved.
// 
//---------------------------------------------------------------------------
using System;
using System.Globalization;
using System.Threading;
 
using System.Windows;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Animation;
 
namespace Microsoft.Windows.Themes
{
    /// <summary>
    /// The ProgressBarHighlightConverter class
    /// </summary>
    public class ProgressBarHighlightConverter : IMultiValueConverter
    {
        /// <summary>
        ///      Creates the brush for the ProgressBar
        /// </summary>
        /// <param name="values">ForegroundBrush, IsIndeterminate, Width, Height</param>
        /// <param name="targetType"></param>
        /// <param name="parameter"></param>
        /// <param name="culture"></param>
        /// <returns>Brush for the ProgressBar</returns>
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            //
            // Parameter Validation
            //
            Type doubleType = typeof(double);
            if (values == null ||
                (values.Length != 3) ||
                (values[0] == null)  ||
                (values[1] == null)  ||
                (values[2] == null)  ||
                !typeof(Brush).IsAssignableFrom(values[0].GetType()) || 
                !doubleType.IsAssignableFrom(values[1].GetType()) ||
                !doubleType.IsAssignableFrom(values[2].GetType()))
            {
                return null;
            }
         
            //
            // Conversion
            //
 
            Brush brush = (Brush)values[0];
            double width = (double)values[1];
            double height = (double)values[2];
 
            // if an invalid height, return a null brush
            if (width <= 0.0 || Double.IsInfinity(width) || Double.IsNaN(width) ||
                height <= 0.0 || Double.IsInfinity(height) || Double.IsNaN(height) )
            {
                return null;
            }
 
            DrawingBrush newBrush = new DrawingBrush();
 
            // Create a Drawing Brush that is 2x longer than progress bar track
            //
            // +-------------+..............
            // | highlight   | empty       :  
            // +-------------+.............:
            //
            //  This brush will animate to the right.
 
            double twiceWidth = width * 2.0;
 
            // Set the viewport and viewbox to the 2*size of the progress region
            newBrush.Viewport = newBrush.Viewbox = new Rect(-width, 0, twiceWidth, height);
            newBrush.ViewportUnits = newBrush.ViewboxUnits = BrushMappingMode.Absolute;
                        
            newBrush.TileMode = TileMode.None;
            newBrush.Stretch = Stretch.None;
 
            DrawingGroup myDrawing = new DrawingGroup();
            DrawingContext myDrawingContext = myDrawing.Open();
 
            // Draw the highlight
            myDrawingContext.DrawRectangle(brush, null, new Rect(-width, 0, width, height));
 
 
            // Animate the Translation
 
            TimeSpan translateTime = TimeSpan.FromSeconds(twiceWidth / 200.0); // travel at 200px /second
            TimeSpan pauseTime = TimeSpan.FromSeconds(1.0);  // pause 1 second between animations
 
            DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
            animation.BeginTime = TimeSpan.Zero;
            animation.Duration = new Duration(translateTime + pauseTime);
            animation.RepeatBehavior = RepeatBehavior.Forever;
            animation.KeyFrames.Add(new LinearDoubleKeyFrame(twiceWidth, translateTime));
 
            TranslateTransform translation = new TranslateTransform();
 
            // Set the animation to the XProperty
            translation.BeginAnimation(TranslateTransform.XProperty, animation);
 
            // Set the animated translation on the brush
            newBrush.Transform = translation;
 
                       
            myDrawingContext.Close();
            newBrush.Drawing = myDrawing;
 
            return newBrush;
        }
 
        /// <summary>
        /// Not Supported
        /// </summary>
        /// <param name="value">value, as produced by target</param>
        /// <param name="targetTypes">target types</param>
        /// <param name="parameter">converter parameter</param>
        /// <param name="culture">culture information</param>
        /// <returns>Nothing</returns>
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            return null;
        }
    }
}