Browse Source

In order to reliably support the different numeric data types, I need to create a specific control for each data type. So instead of copying and pasting I am going to try to create a generic base class that has most of the logic in it. This will make the NumericUpDown control obsolete and it will be removed from the toolkit. The new controls will be DecimalUpDown, DoubleUpDown, and IntegerUpDown.

pull/1645/head
brianlagunas_cp 16 years ago
parent
commit
9d85504a12
  1. 13
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/InputBase.cs
  2. 264
      ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/UpDownBase.cs

13
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/InputBase.cs

@ -21,23 +21,24 @@ namespace Microsoft.Windows.Controls.Primitives
#region Text
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(InputBase), new PropertyMetadata(default(String), OnTextPropertyChanged));
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(InputBase), new UIPropertyMetadata(default(String), OnTextChanged));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
InputBase input = (InputBase)d;
input.OnTextChanged((string)e.OldValue, (string)e.NewValue);
InputBase inputBase = o as InputBase;
if (inputBase != null)
inputBase.OnTextChanged((string)e.OldValue, (string)e.NewValue);
}
protected virtual void OnTextChanged(string previousValue, string currentValue)
protected virtual void OnTextChanged(string oldValue, string newValue)
{
}
}
#endregion //Text

264
ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/UpDownBase.cs

@ -186,4 +186,268 @@ namespace Microsoft.Windows.Controls.Primitives
#endregion //Methods
}
/// <summary>
/// This is going to be the new UpDownBase class. In order to reliably support the different numeric data types, I need to create a specific control for each data type.
/// So instead of copying and pasting I am going to try to create a generic base class that has most of the logic in it. This will make the NumericUpDown control obsolete
/// and it will be removed from the toolkit. The new controls will be DecimalUpDown, DoubleUpDown, and IntegerUpDown.
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class UpDownBase<T> : InputBase
{
#region Members
/// <summary>
/// Name constant for Text template part.
/// </summary>
internal const string ElementTextName = "TextBox";
/// <summary>
/// Name constant for Spinner template part.
/// </summary>
internal const string ElementSpinnerName = "Spinner";
/// <summary>
/// Flags if the Text and Value properties are in the process of being sync'd
/// </summary>
private bool _isSyncingTextAndValueProperties;
#endregion //Members
#region Properties
protected TextBox TextBox { get; private set; }
internal Spinner Spinner { get; private set; }
#region AllowSpin
public static readonly DependencyProperty AllowSpinProperty = DependencyProperty.Register("AllowSpin", typeof(bool), typeof(UpDownBase<T>), new UIPropertyMetadata(true));
public bool AllowSpin
{
get { return (bool)GetValue(AllowSpinProperty); }
set { SetValue(AllowSpinProperty, value); }
}
#endregion //AllowSpin
#region ShowButtonSpinner
public static readonly DependencyProperty ShowButtonSpinnerProperty = DependencyProperty.Register("ShowButtonSpinner", typeof(bool), typeof(UpDownBase<T>), new UIPropertyMetadata(true));
public bool ShowButtonSpinner
{
get { return (bool)GetValue(ShowButtonSpinnerProperty); }
set { SetValue(ShowButtonSpinnerProperty, value); }
}
#endregion //ShowButtonSpinner
#region Value
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(T), typeof(UpDownBase<T>), new UIPropertyMetadata(default(T), OnValueChanged, OnCoerceValue));
public T Value
{
get { return (T)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static object OnCoerceValue(DependencyObject o, object value)
{
UpDownBase<T> upDownBase = o as UpDownBase<T>;
if (upDownBase != null)
return upDownBase.OnCoerceValue((T)value);
else
return value;
}
protected virtual T OnCoerceValue(T value)
{
return value;
}
private static void OnValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
UpDownBase<T> upDownBase = o as UpDownBase<T>;
if (upDownBase != null)
upDownBase.OnValueChanged((T)e.OldValue, (T)e.NewValue);
}
protected virtual void OnValueChanged(T oldValue, T newValue)
{
SyncTextAndValueProperties(NumericUpDown.ValueProperty, newValue);
RoutedPropertyChangedEventArgs<T> args = new RoutedPropertyChangedEventArgs<T>(oldValue, newValue);
args.RoutedEvent = NumericUpDown.ValueChangedEvent;
RaiseEvent(args);
}
#endregion //Value
#endregion //Properties
#region Constructors
internal UpDownBase() { }
#endregion //Constructors
#region Base Class Overrides
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
TextBox = GetTemplateChild(ElementTextName) as TextBox;
Spinner = GetTemplateChild(ElementSpinnerName) as Spinner;
Spinner.Spin += OnSpinnerSpin;
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
switch (e.Key)
{
case Key.Up:
{
if (AllowSpin)
DoIncrement();
e.Handled = true;
break;
}
case Key.Down:
{
if (AllowSpin)
DoDecrement();
e.Handled = true;
break;
}
//case Key.Enter:
// {
// if (IsEditable)
// SyncTextAndValueProperties(UpDownBase.TextProperty, TextBox.Text);
// break;
// }
}
}
protected override void OnMouseWheel(MouseWheelEventArgs e)
{
base.OnMouseWheel(e);
if (!e.Handled && AllowSpin)
{
if (e.Delta < 0)
{
DoDecrement();
}
else if (0 < e.Delta)
{
DoIncrement();
}
e.Handled = true;
}
}
protected override void OnTextChanged(string oldValue, string newValue)
{
SyncTextAndValueProperties(InputBase.TextProperty, newValue);
}
#endregion //Base Class Overrides
#region Event Handlers
private void OnSpinnerSpin(object sender, SpinEventArgs e)
{
if (AllowSpin)
OnSpin(e);
}
#endregion //Event Handlers
#region Events
public static readonly RoutedEvent ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler<T>), typeof(NumericUpDown));
public event RoutedPropertyChangedEventHandler<T> ValueChanged
{
add { AddHandler(ValueChangedEvent, value); }
remove { RemoveHandler(ValueChangedEvent, value); }
}
#endregion //Events
#region Methods
protected virtual void OnSpin(SpinEventArgs e)
{
if (e == null)
throw new ArgumentNullException("e");
if (e.Direction == SpinDirection.Increase)
DoIncrement();
else
DoDecrement();
}
/// <summary>
/// Performs an increment if conditions allow it.
/// </summary>
private void DoDecrement()
{
if (Spinner == null || (Spinner.ValidSpinDirection & ValidSpinDirections.Decrease) == ValidSpinDirections.Decrease)
{
OnDecrement();
}
}
/// <summary>
/// Performs a decrement if conditions allow it.
/// </summary>
private void DoIncrement()
{
if (Spinner == null || (Spinner.ValidSpinDirection & ValidSpinDirections.Increase) == ValidSpinDirections.Increase)
{
OnIncrement();
}
}
private 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 (InputBase.TextProperty == p)
{
string text = newValue == null ? String.Empty : newValue.ToString();
SetValue(UpDownBase<T>.ValueProperty, ConvertTextToValue(text));
}
SetValue(InputBase.TextProperty, ConvertValueToText(newValue));
_isSyncingTextAndValueProperties = false;
}
#region Abstract
/// <summary>
/// Called by OnSpin when the spin direction is SpinDirection.Increase.
/// </summary>
protected abstract void OnIncrement();
/// <summary>
/// Called by OnSpin when the spin direction is SpinDirection.Descrease.
/// </summary>
protected abstract void OnDecrement();
protected abstract T ConvertTextToValue(string text);
protected abstract string ConvertValueToText(object value);
#endregion //Abstract
#endregion //Methods
}
}

Loading…
Cancel
Save