using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.ComponentModel; using System.Windows.Controls.Primitives; using System.Windows; namespace RateBar { /// /// Represents a Progress Bar that also reports back a Rate /// public class RateBase : RangeBase { /// /// Initializes a new instance of the class. /// protected RateBase() { } /// /// Initializes the class. /// static RateBase() { RateChangedEvent = EventManager.RegisterRoutedEvent("RateChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(RateBase)); RateProperty = DependencyProperty.Register("Rate", typeof(double), typeof(RateBase), new FrameworkPropertyMetadata(0.0, FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(RateBase.OnRateChanged)), new ValidateValueCallback(RateBase.IsValidDoubleValue)); CaptionProperty = DependencyProperty.Register("Caption", typeof(String), typeof(RateBase), new PropertyMetadata(String.Empty, new PropertyChangedCallback(OnCaptionChanged))); MinimumRateProperty = DependencyProperty.Register("RateMinimum", typeof(double), typeof(RateBase), new FrameworkPropertyMetadata(0.0, new PropertyChangedCallback(RateBase.OnMinimumRateChanged)), new ValidateValueCallback(RateBase.IsValidDoubleValue)); MaximumRateProperty = DependencyProperty.Register("RateMaximum", typeof(double), typeof(RateBase), new FrameworkPropertyMetadata(1.0, new PropertyChangedCallback(RateBase.OnMaximumRateChanged), new CoerceValueCallback(RateBase.CoerceMaximumRate)), new ValidateValueCallback(RateBase.IsValidDoubleValue)); } #region DependencyProperties /// /// Identifies the RateChanged routed event. /// public static readonly RoutedEvent RateChangedEvent; /// /// Identifies the CaptionChanged routed event. /// public static readonly RoutedEvent CaptionChangedEvent; /// /// Identifies the Rate dependency property. /// public static readonly DependencyProperty RateProperty; /// /// Identifies the RateMinimumProperty dependency property. /// public static readonly DependencyProperty MinimumRateProperty; /// /// Identifies the RateMaximumProperty dependency property. /// public static readonly DependencyProperty MaximumRateProperty; /// /// Identifies the Caption dependency property. /// public static readonly DependencyProperty CaptionProperty; #endregion #region Events /// /// Occurs when the rate changes. /// public event RoutedPropertyChangedEventHandler RateChanged; /// /// Occurs when the rate caption changes. /// public event RoutedPropertyChangedEventHandler CaptionChanged; #endregion #region Properties /// /// Gets or sets the current rate of the rate control. /// [Category("Behaviour"), Bindable(true)] public Double Rate { get { return (Double)base.GetValue(RateProperty); } set { Rescale(value); base.SetValue(RateProperty, value); } } /// /// Provide a change for the RateMaximum to be modified for /// re-scaling any graphs etc. /// /// The current rate protected virtual void Rescale(Double rate) { // Attempt to keep a threshold of 80%, if the // rate increases above this threshold then // increase it. This prevents a graph that just // gets completely full. if (rate > (this.RateMaximum * 0.8)) this.RateMaximum = rate * 1.2; } /// /// Gets or sets the current minimum rate of the rate control. /// [Category("Behaviour"), Bindable(true)] public Double RateMinimum { get { return (Double)base.GetValue(MinimumRateProperty); } set { base.SetValue(MinimumRateProperty, value); } } /// /// Gets or sets the current maximum rate of the rate control. /// [Category("Behaviour"), Bindable(true)] public Double RateMaximum { get { return (Double)base.GetValue(MaximumRateProperty); } set { base.SetValue(MaximumRateProperty, value); } } /// /// Gets or sets the caption for the rate control /// [Category("Behaviour"), Bindable(true)] public String Caption { get { return (String)base.GetValue(CaptionProperty); } set { base.SetValue(CaptionProperty, value); } } #endregion #region Methods /// /// Called when caption changes. /// /// The old value. /// The new value. protected virtual void OnCaptionChanged(String oldValue, String newValue) { RoutedPropertyChangedEventArgs e = new RoutedPropertyChangedEventArgs(oldValue, newValue); e.RoutedEvent = CaptionChangedEvent; if (e.RoutedEvent != null) { base.RaiseEvent(e); } } /// /// Coerces the maximum rate. /// /// The d. /// The value. /// private static object CoerceMaximumRate(DependencyObject d, object value) { RateBase element = (RateBase)d; double minimum = element.RateMinimum; if (((double)value) < minimum) { return minimum; } return value; } /// /// Called when the property changes. /// /// Old value of the property. /// New value of the property. protected virtual void OnMaximumRateChanged(double oldMaximum, double newMaximum) { } /// /// Called when [minimum rate changed]. /// /// The old minimum. /// The new minimum. protected virtual void OnMinimumRateChanged(double oldMinimum, double newMinimum) { } /// /// Called when the caption changes. /// /// The DependencyObject (RateBase). /// The instance containing the event data. private static void OnCaptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RateBase element = (RateBase)d; element.OnCaptionChanged((String)e.OldValue, (String)e.NewValue); } /// /// Called when maximum rate changes. /// /// The DependencyObject (RateBase). /// The instance containing the event data. private static void OnMaximumRateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RateBase element = (RateBase)d; element.CoerceValue(RateProperty); element.OnMaximumRateChanged((double)e.OldValue, (double)e.NewValue); } /// /// Called when minimum rate changes. /// /// The DependencyObject (RateBase). /// The instance containing the event data. private static void OnMinimumRateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RateBase element = (RateBase)d; element.CoerceValue(MaximumRateProperty); element.CoerceValue(RateProperty); element.OnMinimumRateChanged((double)e.OldValue, (double)e.NewValue); } /// /// Called when the rate changes. /// /// The DependencyObject (RateBase). /// The instance containing the event data. private static void OnRateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { RateBase element = (RateBase)d; element.OnRateChanged((double)e.OldValue, (double)e.NewValue); } /// /// Called when rate changes. /// /// The old value. /// The new value. protected virtual void OnRateChanged(double oldValue, double newValue) { RoutedPropertyChangedEventArgs e = new RoutedPropertyChangedEventArgs(oldValue, newValue); e.RoutedEvent = RateChangedEvent; base.RaiseEvent(e); } /// /// Determines whether the value is a valid double value. /// /// The value. private static bool IsValidDoubleValue(object value) { double num = (double)value; return (!Double.IsNaN(num) && !double.IsInfinity(num)); } #endregion } }