diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs index d669a3dd..aed90390 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs @@ -260,14 +260,14 @@ namespace Microsoft.Windows.Controls _isSyncingTextAndValueProperties = true; //this only occures when the user typed in the value - if (NumericUpDown.TextProperty == p) + if (UpDownBase.TextProperty == p) { - SetValue(NumericUpDown.ValueProperty, ParseValue(newValue.ToString())); + SetValue(UpDownBase.ValueProperty, ParseValue(newValue.ToString())); } //we need to update the text no matter what because the user could have used the spin buttons to change dthe value //or typed in the textbox so we need to reformat the entered value. - SetValue(NumericUpDown.TextProperty, FormatValue()); + SetValue(UpDownBase.TextProperty, FormatValue()); _isSyncingTextAndValueProperties = false; } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj index fe315047..738ae7e2 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj @@ -145,7 +145,6 @@ - - + - + @@ -377,7 +377,7 @@ - + @@ -386,7 +386,7 @@ - + @@ -923,4 +923,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs b/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs new file mode 100644 index 00000000..aed90390 --- /dev/null +++ b/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/UpDownBase/UpDownBase.cs @@ -0,0 +1,321 @@ +using System; +using System.Windows.Input; +using System.Windows.Controls; +using System.Windows; + +namespace Microsoft.Windows.Controls +{ + public abstract class UpDownBase : Control + { + #region Members + + /// + /// Name constant for Text template part. + /// + internal const string ElementTextName = "Text"; + + /// + /// Name constant for Spinner template part. + /// + internal const string ElementSpinnerName = "Spinner"; + + /// + /// Flags if the Text and Value properties are in the process of being sync'd + /// + bool _isSyncingTextAndValueProperties; + + #endregion //Members + + #region Properties + + #region Value + + public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(T), typeof(UpDownBase), new FrameworkPropertyMetadata(default(T), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValuePropertyChanged)); + public virtual T Value + { + get { return (T)GetValue(ValueProperty); } + set { SetValue(ValueProperty, value); } + } + + private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + UpDownBase udb = (UpDownBase)d; + T oldValue = (T)e.OldValue; + T newValue = (T)e.NewValue; + + udb.SyncTextAndValueProperties(e.Property, e.NewValue); + + RoutedPropertyChangedEventArgs changedArgs = new RoutedPropertyChangedEventArgs(oldValue, newValue); + udb.OnValueChanged(changedArgs); + } + + protected virtual void OnValueChanged(RoutedPropertyChangedEventArgs e) + { + if (ValueChanged != null) + ValueChanged(this, e); + } + + #endregion //Value + + #region Text + + public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(UpDownBase), new FrameworkPropertyMetadata("0", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextPropertyChanged)); + public string Text + { + get { return (string)GetValue(TextProperty); } + set { SetValue(TextProperty, value); } + } + + private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + UpDownBase udb = (UpDownBase)d; + udb.SyncTextAndValueProperties(e.Property, e.NewValue); + } + + #endregion //Text + + #region IsEditable + + public static readonly DependencyProperty IsEditableProperty = DependencyProperty.Register("IsEditable", typeof(bool), typeof(UpDownBase), new PropertyMetadata(true, OnIsEditablePropertyChanged)); + public bool IsEditable + { + get { return (bool)GetValue(IsEditableProperty); } + set { SetValue(IsEditableProperty, value); } + } + + private static void OnIsEditablePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + UpDownBase source = d as UpDownBase; + source.OnIsEditableChanged((bool)e.OldValue, (bool)e.NewValue); + } + + protected virtual void OnIsEditableChanged(bool oldValue, bool newValue) + { + if (TextBox != null) + TextBox.IsReadOnly = !IsEditable; + } + + #endregion //IsEditable + + internal TextBox TextBox { get; private set; } + + private Spinner _spinner; + internal Spinner Spinner + { + get { return _spinner; } + private set + { + _spinner = value; + _spinner.Spin += OnSpinnerSpin; + } + } + + #endregion //Properties + + #region Constructors + + protected UpDownBase() { } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + TextBox = GetTemplateChild(ElementTextName) as TextBox; + Spinner = GetTemplateChild(ElementSpinnerName) as Spinner; + + if (TextBox != null) + TextBox.IsReadOnly = !IsEditable; + } + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + switch (e.Key) + { + case Key.Up: + { + DoIncrement(); + e.Handled = true; + break; + } + case Key.Down: + { + DoDecrement(); + e.Handled = true; + break; + } + case Key.Enter: + { + SyncTextAndValueProperties(UpDownBase.TextProperty, TextBox.Text); + break; + } + } + } + + protected override void OnMouseWheel(MouseWheelEventArgs e) + { + base.OnMouseWheel(e); + + if (!e.Handled) + { + if (e.Delta < 0) + { + DoDecrement(); + } + else if (0 < e.Delta) + { + DoIncrement(); + } + + e.Handled = true; + } + } + + #endregion //Base Class Overrides + + #region Methods + + #region Abstract + + /// + /// Called by ApplyValue to parse user input. + /// + /// User input. + /// Value parsed from user input. + protected abstract T ParseValue(string text); + + /// + /// Renders the value property into the textbox text. + /// + /// Formatted Value. + protected internal abstract string FormatValue(); + + /// + /// Called by OnSpin when the spin direction is SpinDirection.Increase. + /// + protected abstract void OnIncrement(); + + /// + /// Called by OnSpin when the spin direction is SpinDirection.Descrease. + /// + protected abstract void OnDecrement(); + + #endregion //Abstract + + #region Protected + + /// + /// GetValue override to return Value property as object type. + /// + /// The Value property as object type. + protected object GetValue() + { + return Value; + } + + /// + /// SetValue override to set value to Value property. + /// + /// New value. + protected void SetValue(object value) + { + Value = (T)value; + } + + #endregion //Protected + + #region Private + + /// + /// Performs an increment if conditions allow it. + /// + private void DoDecrement() + { + if (Spinner == null || (Spinner.ValidSpinDirection & ValidSpinDirections.Decrease) == ValidSpinDirections.Decrease) + { + OnDecrement(); + } + } + + /// + /// Performs a decrement if conditions allow it. + /// + private void DoIncrement() + { + if (Spinner == null || (Spinner.ValidSpinDirection & ValidSpinDirections.Increase) == ValidSpinDirections.Increase) + { + OnIncrement(); + } + } + + protected void SyncTextAndValueProperties(DependencyProperty p, object newValue) + { + //prevents recursive syncing properties + if (_isSyncingTextAndValueProperties) + return; + + _isSyncingTextAndValueProperties = true; + + //this only occures when the user typed in the value + if (UpDownBase.TextProperty == p) + { + SetValue(UpDownBase.ValueProperty, ParseValue(newValue.ToString())); + } + + //we need to update the text no matter what because the user could have used the spin buttons to change dthe value + //or typed in the textbox so we need to reformat the entered value. + SetValue(UpDownBase.TextProperty, FormatValue()); + + _isSyncingTextAndValueProperties = false; + } + + #endregion //Private + + #region Virtual + + /// + /// Occurs when the spinner spins. + /// + /// Event args. + protected virtual void OnSpin(SpinEventArgs e) + { + if (e == null) + throw new ArgumentNullException("e"); + + if (e.Direction == SpinDirection.Increase) + DoIncrement(); + else + DoDecrement(); + } + + #endregion //Virtual + + #endregion //Methods + + #region Event Handlers + + /// + /// Event handler for Spinner template part's Spin event. + /// + /// The Spinner template part. + /// Event args. + private void OnSpinnerSpin(object sender, SpinEventArgs e) + { + OnSpin(e); + } + + #endregion //Event Handlers + + #region Events + + /// + /// Occurs when Value property has changed. + /// + public event RoutedPropertyChangedEventHandler ValueChanged; + + #endregion //Events + } +} diff --git a/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj b/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj index 9b450cc2..bd366366 100644 --- a/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj +++ b/ExtendedWPFToolkitSolution_35/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj @@ -52,6 +52,10 @@ + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -59,6 +63,11 @@ + + + + + @@ -66,7 +75,9 @@ + + Code @@ -81,11 +92,17 @@ True + + + RichTextBoxFormatBar.xaml + + + @@ -104,6 +121,18 @@ + + + + + + + + + + + +