|
|
|
@ -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
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raises the click event.
|
|
|
|
/// </summary>
|
|
|
|
private void RaiseClickEvent() |
|
|
|
{ |
|
|
|
RoutedEventArgs args = new RoutedEventArgs(SplitButton.ClickEvent, this); |
|
|
|
RaiseEvent(args); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raises the command's Execute event.
|
|
|
|
/// </summary>
|
|
|
|
private void RaiseCommand() |
|
|
|
{ |
|
|
|
if (Command != null) |
|
|
|
{ |
|
|
|
RoutedCommand routedCommand = Command as RoutedCommand; |
|
|
|
|
|
|
|
if (routedCommand == null) |
|
|
|
((ICommand)Command).Execute(CommandParameter); |
|
|
|
else |
|
|
|
routedCommand.Execute(CommandParameter, CommandTarget); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Unhooks a command from the Command property.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="oldCommand">The old command.</param>
|
|
|
|
/// <param name="newCommand">The new command.</param>
|
|
|
|
private void UnhookCommand(ICommand oldCommand, ICommand newCommand) |
|
|
|
{ |
|
|
|
EventHandler handler = CanExecuteChanged; |
|
|
|
oldCommand.CanExecuteChanged -= handler; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Hooks up a command to the CanExecuteChnaged event handler.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="oldCommand">The old command.</param>
|
|
|
|
/// <param name="newCommand">The new command.</param>
|
|
|
|
private void HookUpCommand(ICommand oldCommand, ICommand newCommand) |
|
|
|
{ |
|
|
|
EventHandler handler = new EventHandler(CanExecuteChanged); |
|
|
|
canExecuteChangedHandler = handler; |
|
|
|
if (newCommand != null) |
|
|
|
newCommand.CanExecuteChanged += canExecuteChangedHandler; |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Closes the drop down.
|
|
|
|
/// </summary>
|
|
|
|
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
|
|
|
|
} |
|
|
|
} |
|
|
|
|