diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/SplitButton/SplitButton.cs b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/SplitButton/SplitButton.cs index 67c1f202..e667053d 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/SplitButton/SplitButton.cs +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/SplitButton/SplitButton.cs @@ -3,13 +3,14 @@ using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Controls.Primitives; +using System.ComponentModel; namespace Microsoft.Windows.Controls { - public class SplitButton : ContentControl + public class SplitButton : ContentControl, ICommandSource { #region Members - + Button _actionButton; ToggleButton _toggleButton; Popup _popup; @@ -51,7 +52,7 @@ namespace Microsoft.Windows.Controls protected virtual void OnDropDownContentChanged(object oldValue, object newValue) { // TODO: Add your property changed side-effects. Descendants can override as well. - } + } #endregion //DropDownContent @@ -80,31 +81,44 @@ namespace Microsoft.Windows.Controls #endregion //Properties + #region Events + + public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(SplitButton)); + public event RoutedEventHandler Click + { + add { AddHandler(ClickEvent, value); } + remove { RemoveHandler(ClickEvent, value); } + } + + #endregion //Events + #region Base Class Overrides public override void OnApplyTemplate() { base.OnApplyTemplate(); + _actionButton = (Button)GetTemplateChild("PART_ActionButton"); + _actionButton.Click += ActionButton_Click; + _toggleButton = (ToggleButton)GetTemplateChild("PART_ToggleButton"); - _toggleButton.Click += ToggleButton_Click; - + _popup = (Popup)GetTemplateChild("PART_Popup"); - _popup.Opened += Popup_Opened; + //_popup.Opened += Popup_Opened; } #endregion //Base Class Overrides #region Event Handlers - void ToggleButton_Click(object sender, RoutedEventArgs e) + void ActionButton_Click(object sender, RoutedEventArgs e) { - + OnClick(); } void Popup_Opened(object sender, EventArgs e) { - + } private void OnKeyDown(object sender, KeyEventArgs e) @@ -112,7 +126,6 @@ namespace Microsoft.Windows.Controls switch (e.Key) { case Key.Escape: - case Key.Tab: { CloseDropDown(); break; @@ -125,10 +138,88 @@ namespace Microsoft.Windows.Controls CloseDropDown(); } + void CanExecuteChanged(object sender, EventArgs e) + { + if (Command != null) + { + RoutedCommand command = Command as RoutedCommand; + + // If a RoutedCommand. + if (command != null) + IsEnabled = command.CanExecute(CommandParameter, CommandTarget) ? true : false; + // If a not RoutedCommand. + else + IsEnabled = Command.CanExecute(CommandParameter) ? true : false; + } + } + #endregion //Event Handlers #region Methods + #region Protected + + protected virtual void OnClick() + { + RaiseClickEvent(); + RaiseCommand(); + } + #endregion //Protected + + #region Private + + /// + /// Raises the click event. + /// + private void RaiseClickEvent() + { + RoutedEventArgs args = new RoutedEventArgs(SplitButton.ClickEvent, this); + RaiseEvent(args); + } + + /// + /// Raises the command's Execute event. + /// + private void RaiseCommand() + { + if (Command != null) + { + RoutedCommand routedCommand = Command as RoutedCommand; + + if (routedCommand == null) + ((ICommand)Command).Execute(CommandParameter); + else + routedCommand.Execute(CommandParameter, CommandTarget); + } + } + + /// + /// Unhooks a command from the Command property. + /// + /// The old command. + /// The new command. + private void UnhookCommand(ICommand oldCommand, ICommand newCommand) + { + EventHandler handler = CanExecuteChanged; + oldCommand.CanExecuteChanged -= handler; + } + + /// + /// Hooks up a command to the CanExecuteChnaged event handler. + /// + /// The old command. + /// The new command. + private void HookUpCommand(ICommand oldCommand, ICommand newCommand) + { + EventHandler handler = new EventHandler(CanExecuteChanged); + canExecuteChangedHandler = handler; + if (newCommand != null) + newCommand.CanExecuteChanged += canExecuteChangedHandler; + } + + /// + /// Closes the drop down. + /// private void CloseDropDown() { if (IsOpen) @@ -136,6 +227,57 @@ namespace Microsoft.Windows.Controls ReleaseMouseCapture(); } + #endregion //Private + #endregion //Methods + + #region ICommandSource Members + + // Keeps a copy of the CanExecuteChnaged handler so it doesn't get garbage collected. + private static EventHandler canExecuteChangedHandler; + + #region Command + + public static readonly DependencyProperty CommandProperty = DependencyProperty.Register("Command", typeof(ICommand), typeof(SplitButton), new PropertyMetadata((ICommand)null, OnCommandChanged)); + [TypeConverter(typeof(CommandConverter))] + public ICommand Command + { + get { return (ICommand)GetValue(CommandProperty); } + set { SetValue(CommandProperty, value); } + } + + private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + SplitButton splitButton = d as SplitButton; + if (splitButton != null) + splitButton.OnCommandChanged((ICommand)e.OldValue, (ICommand)e.NewValue); + } + + protected virtual void OnCommandChanged(ICommand oldValue, ICommand newValue) + { + // If old command is not null, then we need to remove the handlers. + if (oldValue != null) + UnhookCommand(oldValue, newValue); + + HookUpCommand(oldValue, newValue); + } + + #endregion //Command + + public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(SplitButton), new PropertyMetadata(null)); + public object CommandParameter + { + get { return GetValue(CommandParameterProperty); } + set { SetValue(CommandParameterProperty, value); } + } + + public static readonly DependencyProperty CommandTargetProperty = DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(SplitButton), new PropertyMetadata(null)); + public IInputElement CommandTarget + { + get { return (IInputElement)GetValue(CommandTargetProperty); } + set { SetValue(CommandTargetProperty, value); } + } + + #endregion } } diff --git a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml index 30f61b90..c865fa9f 100644 --- a/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml +++ b/ExtendedWPFToolkitSolution/Src/WPFToolkit.Extended/Themes/Generic.xaml @@ -1216,7 +1216,7 @@ -