using System; using System.ComponentModel; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; namespace QuikDawEditor { public partial class NumericSpinner : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public delegate void ValueChangedHandler(double value); public event ValueChangedHandler ValueChanged; public NumericSpinner() { InitializeComponent(); Step = 1; UpTimer.Tick += UpTimer_Tick; DownTimer.Tick += DownTimer_Tick; DownTimer.Interval = new TimeSpan(0, 0, 0, 0, 200); UpTimer.Interval = new TimeSpan(0, 0, 0, 0, 200); } public string ValueString { get { return Value.ToString(); } } private double _Step = 1; public double Step { get { return _Step; } set { _Step = value; } } private void CmdUp_Click(object sender, RoutedEventArgs e) { Value += (Keyboard.IsKeyDown(Key.LeftCtrl) ? Step * 10 : Step); } private void CmdDown_Click(object sender, RoutedEventArgs e) { Value -= (Keyboard.IsKeyDown(Key.LeftCtrl) ? Step * 10 : Step); } internal DispatcherTimer DownTimer = new DispatcherTimer(); internal DispatcherTimer UpTimer = new DispatcherTimer(); private void DownTimer_Tick(object sender, EventArgs e) { Value -= Step; } private void UpTimer_Tick(object sender, EventArgs e) { Value += Step; } private void CmdDown_PreviewMouseDown(object sender, MouseButtonEventArgs e) { DownTimer.Start(); } private void CmdDown_PreviewMouseUp(object sender, MouseButtonEventArgs e) { DownTimer.Stop(); } private void CmdUp_PreviewMouseDown(object sender, MouseButtonEventArgs e) { UpTimer.Start(); } private void CmdUp_PreviewMouseUp(object sender, MouseButtonEventArgs e) { UpTimer.Stop(); } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(NumericSpinner), new FrameworkPropertyMetadata(15D, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((NumericSpinner)o).ValuePropertyChanged((double)e.NewValue))); public double Value { get { return (double)GetValue(ValueProperty); } set { if (value < MinValue) value = MinValue; if (value > MaxValue) value = MaxValue; NotifyPropertyChanged(nameof(ValueString)); SetValue(ValueProperty, value); } } private void ValuePropertyChanged(double Val) { Value = Val; if (ValueChanged!= null) ValueChanged(Val); } public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(NumericSpinner), new FrameworkPropertyMetadata(240D, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((NumericSpinner)o).MaxValuePropertyChanged((double)e.NewValue))); public double MaxValue { get { return (double)GetValue(MaxValueProperty); } set { SetValue(MaxValueProperty, value); } } private void MaxValuePropertyChanged(double Val) { MaxValue = Val; } public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(NumericSpinner), new FrameworkPropertyMetadata(240D, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, (o, e) => ((NumericSpinner)o).MinValuePropertyChanged((double)e.NewValue))); public double MinValue { get { return (double)GetValue(MinValueProperty); } set { SetValue(MinValueProperty, value); } } private void MinValuePropertyChanged(double Val) { MinValue = Val; } } }