Progress bar with dynamic text & text color update

前端 未结 3 1148
谎友^
谎友^ 2020-11-30 03:26

I\'ve a progressbar whose text changes dynamically. I want to update the appearance of it such that as soon as progress comes over text then text color should update. Someth

3条回答
  •  暗喜
    暗喜 (楼主)
    2020-11-30 03:53

    Here's a solution in Silverlight but it should be easy to convert it to WPF.

    I'm using linear gradient brush to change the text color in the text block, I created a user control with a progress bar and a text block, let's call it "SpecialProgressBar"

    Here's the XAML:

    
    
        
    
            
    
            
        
    
    

    And here's the code:

    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    
    namespace TestSilverlightApplication
    {
        public partial class SpecialProgressBar : UserControl
        {
            private Point _textBlockPosition;
            private readonly LinearGradientBrush _linearGradientBrush;
            private readonly GradientStop _gradientStop;
    
            public SpecialProgressBar()
            {
                InitializeComponent();
    
                // will be changing this gradient stop as the progress bar value changes
                _gradientStop = new GradientStop
                {
                    Color = Colors.Black,
                    Offset = 0
                };
    
                // the default brush we want to start with,
                // you might want to play with the start point x value to get the effect you want
                _linearGradientBrush = new LinearGradientBrush
                {
                    StartPoint = new Point(-0.2, 0.5),
                    EndPoint = new Point(1, 0.5),
                    GradientStops = new GradientStopCollection
                    {
                        _gradientStop,
                        new GradientStop
                        {
                            Color = Colors.Black,
                            Offset = 1
                        }
                    }
                };
    
                // set the brush to the text block 
                textBlock.Foreground = _linearGradientBrush;
    
                Loaded += new RoutedEventHandler(SpecialProgressBar_Loaded);
                progressBar.ValueChanged += new RoutedPropertyChangedEventHandler(progressBar_ValueChanged);
            }
    
            private void SpecialProgressBar_Loaded(object sender, RoutedEventArgs e)
            {
                // center text block on top of the progress bar
                _textBlockPosition = new Point(progressBar.Width / 2 - textBlock.ActualWidth / 2,
                                               progressBar.Height / 2 - textBlock.ActualHeight / 2);
    
                textBlock.SetValue(Canvas.LeftProperty, _textBlockPosition.X);
                textBlock.SetValue(Canvas.TopProperty, _textBlockPosition.Y);
            }
    
            private void progressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
            {
                // print out the value in the text block
                textBlock.Text = string.Concat(e.NewValue, " of ", progressBar.Maximum);
    
                // get the value relative to the size of the progress bar
                var x = e.NewValue / progressBar.Maximum * progressBar.Width;             
    
                // if the value is equal to or greater than the position of the text block on the canvas (on the progress bar)
                // then we want to change the gradient offset and color.
                if (x >= _textBlockPosition.X)
                {
                    _gradientStop.Offset += 0.1 * textBlock.ActualWidth / progressBar.Width;
                    _gradientStop.Color = Colors.White;
    
                    // when we pass the end of the text block we don't need the gradient any more,
                    // replace it with a solid white color
                    if (_gradientStop.Offset >= 1)
                    {
                        textBlock.Foreground = new SolidColorBrush(Colors.White);
                    }
                }
            }
        }
    }
    

    The last step is to add the user control to a page (or another user control)

    
    
        
            
        
    
    

    And to test it out I added a timer to change the progress bar value:

    using System;
    using System.Windows.Controls;
    using System.Windows.Threading;
    
    namespace TestSilverlightApplication
    {
        public partial class MainPage : UserControl
        {
            public MainPage()
            {
                InitializeComponent();
    
                this.Loaded += new System.Windows.RoutedEventHandler(MainPage_Loaded);
            }
    
            private void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
            {
                var timer = new DispatcherTimer();
                timer.Tick += (s, args) => specialProgressBar.progressBar.Value += 1;
                timer.Interval = new TimeSpan(1000000);
                timer.Start();
            }
        }
    }
    

    It looks like this:

    enter image description here

    This is a quick and dirty solution but it's a start, I think. Hope this helps.

提交回复
热议问题