From 308ad9dc8536c80dcd7aee514769854058213b9e Mon Sep 17 00:00:00 2001 From: brianlagunas_cp Date: Fri, 5 Nov 2010 20:04:20 +0000 Subject: [PATCH] initial checkin of new ButtonSpinner control. Allows you to add button spinners to any element and then respond to the Spin event to manipulate that element. To add use the following syntax private void ButtonSpinner_Spin(object sender, Microsoft.Windows.Controls.Primitives.SpinEventArgs e) { int value = String.IsNullOrEmpty(_txtValue.Text) ? 0 : Convert.ToInt32(_txtValue.Text); if (e.Direction == Microsoft.Windows.Controls.Primitives.SpinDirection.Increase) value++; else value--; _txtValue.Text = value.ToString(); } --- .../ButtonSpinner/ButtonSpinner.cs | 192 ++++++++++++++++++ .../Core/Primitives/SpinDirection.cs | 21 ++ .../Core/Primitives/SpinEventArgs.cs | 28 +++ .../Core/Primitives/Spinner.cs | 77 +++++++ .../Core/Primitives/ValidSpinDirections.cs | 26 +++ .../WPFToolkit.Extended/Themes/Generic.xaml | 153 ++++++++++++++ .../WPFToolkit.Extended.csproj | 5 + 7 files changed, 502 insertions(+) create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ButtonSpinner/ButtonSpinner.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinDirection.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinEventArgs.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Spinner.cs create mode 100644 ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValidSpinDirections.cs diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ButtonSpinner/ButtonSpinner.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ButtonSpinner/ButtonSpinner.cs new file mode 100644 index 00000000..467f6c85 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/ButtonSpinner/ButtonSpinner.cs @@ -0,0 +1,192 @@ +using System; +using System.Windows; +using System.Windows.Input; +using System.Windows.Markup; +using System.Windows.Controls.Primitives; +using Microsoft.Windows.Controls.Primitives; + +namespace Microsoft.Windows.Controls +{ + /// + /// Represents a spinner control that includes two Buttons. + /// + [ContentProperty("Content")] + public class ButtonSpinner : Spinner + { + #region Properties + + #region Content + + /// + /// Identifies the Content dependency property. + /// + public static readonly DependencyProperty ContentProperty = DependencyProperty.Register("Content", typeof(object), typeof(ButtonSpinner), new PropertyMetadata(null, OnContentPropertyChanged)); + public object Content + { + get { return GetValue(ContentProperty) as object; } + set { SetValue(ContentProperty, value); } + } + + /// + /// ContentProperty property changed handler. + /// + /// ButtonSpinner that changed its Content. + /// Event arguments. + private static void OnContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ButtonSpinner source = d as ButtonSpinner; + source.OnContentChanged(e.OldValue, e.NewValue); + } + + #endregion //Content + + private ButtonBase _increaseButton; + /// + /// Gets or sets the IncreaseButton template part. + /// + private ButtonBase IncreaseButton + { + get { return _increaseButton; } + set + { + if (_increaseButton != null) + { + _increaseButton.Click -= OnButtonClick; + } + + _increaseButton = value; + + if (_increaseButton != null) + { + _increaseButton.Click += OnButtonClick; + } + } + } + + + private ButtonBase _decreaseButton; + /// + /// Gets or sets the DecreaseButton template part. + /// + private ButtonBase DecreaseButton + { + get { return _decreaseButton; } + set + { + if (_decreaseButton != null) + { + _decreaseButton.Click -= OnButtonClick; + } + + _decreaseButton = value; + + if (_decreaseButton != null) + { + _decreaseButton.Click += OnButtonClick; + } + } + } + + #endregion //Properties + + #region Constructors + + static ButtonSpinner() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ButtonSpinner), new FrameworkPropertyMetadata(typeof(ButtonSpinner))); + } + + #endregion //Constructors + + #region Base Class Overrides + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + IncreaseButton = GetTemplateChild("IncreaseButton") as ButtonBase; + DecreaseButton = GetTemplateChild("DecreaseButton") as ButtonBase; + + SetButtonUsage(); + } + + #endregion //Base Class Overrides + + /// + /// Occurs when the Content property value changed. + /// + /// The old value of the Content property. + /// The new value of the Content property. + protected virtual void OnContentChanged(object oldValue, object newValue) { } + + /// + /// Handle click event of IncreaseButton and DecreaseButton template parts, + /// translating Click to appropriate Spin event. + /// + /// Event sender, should be either IncreaseButton or DecreaseButton template part. + /// Event args. + private void OnButtonClick(object sender, RoutedEventArgs e) + { + SpinDirection direction = sender == IncreaseButton ? SpinDirection.Increase : SpinDirection.Decrease; + OnSpin(new SpinEventArgs(direction)); + } + + /// + /// Cancel LeftMouseButtonUp events originating from a button that has + /// been changed to disabled. + /// + /// The data for the event. + protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonUp(e); + + Point mousePosition; + if (IncreaseButton != null && IncreaseButton.IsEnabled == false) + { + mousePosition = e.GetPosition(IncreaseButton); + if (mousePosition.X > 0 && mousePosition.X < IncreaseButton.ActualWidth && + mousePosition.Y > 0 && mousePosition.Y < IncreaseButton.ActualHeight) + { + e.Handled = true; + } + } + + if (DecreaseButton != null && DecreaseButton.IsEnabled == false) + { + mousePosition = e.GetPosition(DecreaseButton); + if (mousePosition.X > 0 && mousePosition.X < DecreaseButton.ActualWidth && + mousePosition.Y > 0 && mousePosition.Y < DecreaseButton.ActualHeight) + { + e.Handled = true; + } + } + } + + /// + /// Called when valid spin direction changed. + /// + /// The old value. + /// The new value. + protected override void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue) + { + SetButtonUsage(); + } + + /// + /// Disables or enables the buttons based on the valid spin direction. + /// + private void SetButtonUsage() + { + // buttonspinner adds buttons that spin, so disable accordingly. + if (IncreaseButton != null) + { + IncreaseButton.IsEnabled = ((ValidSpinDirection & ValidSpinDirections.Increase) == ValidSpinDirections.Increase); + } + + if (DecreaseButton != null) + { + DecreaseButton.IsEnabled = ((ValidSpinDirection & ValidSpinDirections.Decrease) == ValidSpinDirections.Decrease); + } + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinDirection.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinDirection.cs new file mode 100644 index 00000000..a5e58cc3 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinDirection.cs @@ -0,0 +1,21 @@ +using System; + +namespace Microsoft.Windows.Controls.Primitives +{ + /// + /// Represents spin directions that could be initiated by the end-user. + /// + /// Preview + public enum SpinDirection + { + /// + /// Represents a spin initiated by the end-user in order to Increase a value. + /// + Increase = 0, + + /// + /// Represents a spin initiated by the end-user in order to Decrease a value. + /// + Decrease = 1 + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinEventArgs.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinEventArgs.cs new file mode 100644 index 00000000..5750f13f --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/SpinEventArgs.cs @@ -0,0 +1,28 @@ +using System; +using System.Windows; + +namespace Microsoft.Windows.Controls.Primitives +{ + /// + /// Provides data for the Spinner.Spin event. + /// + /// Preview + public class SpinEventArgs : RoutedEventArgs + { + /// + /// Gets the SpinDirection for the spin that has been initiated by the + /// end-user. + /// + public SpinDirection Direction { get; private set; } + + /// + /// Initializes a new instance of the SpinEventArgs class. + /// + /// Spin direction. + public SpinEventArgs(SpinDirection direction) + : base() + { + Direction = direction; + } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Spinner.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Spinner.cs new file mode 100644 index 00000000..cb169de9 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/Spinner.cs @@ -0,0 +1,77 @@ +using System; +using System.Windows.Controls; +using System.Windows; + +namespace Microsoft.Windows.Controls.Primitives +{ + /// + /// Base class for controls that represents controls that can spin. + /// + public abstract class Spinner : Control + { + #region Properties + + /// + /// Identifies the ValidSpinDirection dependency property. + /// + public static readonly DependencyProperty ValidSpinDirectionProperty = DependencyProperty.Register("ValidSpinDirection", typeof(ValidSpinDirections), typeof(Spinner), new PropertyMetadata(ValidSpinDirections.Increase | ValidSpinDirections.Decrease, OnValidSpinDirectionPropertyChanged)); + public ValidSpinDirections ValidSpinDirection + { + get { return (ValidSpinDirections)GetValue(ValidSpinDirectionProperty); } + set { SetValue(ValidSpinDirectionProperty, value); } + } + + /// + /// ValidSpinDirectionProperty property changed handler. + /// + /// ButtonSpinner that changed its ValidSpinDirection. + /// Event arguments. + private static void OnValidSpinDirectionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + Spinner source = (Spinner)d; + ValidSpinDirections oldvalue = (ValidSpinDirections)e.OldValue; + ValidSpinDirections newvalue = (ValidSpinDirections)e.NewValue; + source.OnValidSpinDirectionChanged(oldvalue, newvalue); + } + + #endregion //Properties + + /// + /// Occurs when spinning is initiated by the end-user. + /// + public event EventHandler Spin; + + /// + /// Initializes a new instance of the Spinner class. + /// + protected Spinner() { } + + /// + /// Raises the OnSpin event when spinning is initiated by the end-user. + /// + /// Spin event args. + protected virtual void OnSpin(SpinEventArgs e) + { + ValidSpinDirections valid = e.Direction == SpinDirection.Increase ? ValidSpinDirections.Increase : ValidSpinDirections.Decrease; + + if ((ValidSpinDirection & valid) != valid) + { + // spin is not allowed. + throw new InvalidOperationException("Spin action is not valid at this moment."); + } + + EventHandler handler = Spin; + if (handler != null) + { + handler(this, e); + } + } + + /// + /// Called when valid spin direction changed. + /// + /// The old value. + /// The new value. + protected virtual void OnValidSpinDirectionChanged(ValidSpinDirections oldValue, ValidSpinDirections newValue) { } + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValidSpinDirections.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValidSpinDirections.cs new file mode 100644 index 00000000..4099bc25 --- /dev/null +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Core/Primitives/ValidSpinDirections.cs @@ -0,0 +1,26 @@ +using System; + +namespace Microsoft.Windows.Controls.Primitives +{ + /// + /// Represents spin directions that are valid. + /// + [Flags] + public enum ValidSpinDirections + { + /// + /// Can not increase nor decrease. + /// + None = 0, + + /// + /// Can increase. + /// + Increase = 1, + + /// + /// Can decrease. + /// + Decrease = 2 + } +} diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml index c9aa9d50..5c8adc47 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml @@ -926,4 +926,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj index feb35caf..627f466e 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/WPFToolkit.Extended.csproj @@ -64,6 +64,7 @@ + @@ -71,6 +72,10 @@ + + + + Code