diff --git a/MahApps.Metro/Controls/ToggleSwitch.cs b/MahApps.Metro/Controls/ToggleSwitch.cs index 17c752978b..ca87f4e8d3 100644 --- a/MahApps.Metro/Controls/ToggleSwitch.cs +++ b/MahApps.Metro/Controls/ToggleSwitch.cs @@ -10,6 +10,7 @@ using System.Windows.Controls; using System.Windows.Controls.Primitives; using System.Windows.Data; +using System.Windows.Input; using System.Windows.Media; using MahApps.Metro.Converters; @@ -29,16 +30,34 @@ public class ToggleSwitch : ContentControl private const string SwitchPart = "Switch"; private ToggleButton _toggleButton; - private bool _wasContentSet; public static readonly DependencyProperty OnLabelProperty = DependencyProperty.Register("OnLabel", typeof(string), typeof(ToggleSwitch), new PropertyMetadata("On")); public static readonly DependencyProperty OffLabelProperty = DependencyProperty.Register("OffLabel", typeof(string), typeof(ToggleSwitch), new PropertyMetadata("Off")); public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(object), typeof(ToggleSwitch), new PropertyMetadata(null)); public static readonly DependencyProperty HeaderTemplateProperty = DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(ToggleSwitch), new PropertyMetadata(null)); - public static readonly DependencyProperty SwitchForegroundProperty = DependencyProperty.Register("SwitchForeground", typeof(Brush), typeof(ToggleSwitch), null); + + [Obsolete(@"This property will be deleted in the next release. You should use OnSwitchBrush and OffSwitchBrush to change the switch's brushes.")] + public static readonly DependencyProperty SwitchForegroundProperty = DependencyProperty.Register("SwitchForeground", typeof(Brush), typeof(ToggleSwitch), new PropertyMetadata(null, (o, e) => ((ToggleSwitch)o).OnSwitchBrush = e.NewValue as Brush)); + public static readonly DependencyProperty OnSwitchBrushProperty = DependencyProperty.Register("OnSwitchBrush", typeof(Brush), typeof(ToggleSwitch), null); + public static readonly DependencyProperty OffSwitchBrushProperty = DependencyProperty.Register("OffSwitchBrush", typeof(Brush), typeof(ToggleSwitch), null); + + public static readonly DependencyProperty ThumbIndicatorBrushProperty = DependencyProperty.Register("ThumbIndicatorBrush", typeof(Brush), typeof(ToggleSwitch), null); + public static readonly DependencyProperty ThumbIndicatorDisabledBrushProperty = DependencyProperty.Register("ThumbIndicatorDisabledBrush", typeof(Brush), typeof(ToggleSwitch), null); + public static readonly DependencyProperty ThumbIndicatorWidthProperty = DependencyProperty.Register("ThumbIndicatorWidth", typeof(double), typeof(ToggleSwitch), new PropertyMetadata(13d)); + public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register("IsChecked", typeof(bool?), typeof(ToggleSwitch), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnIsCheckedChanged)); + + public static readonly DependencyProperty CheckChangedCommandProperty = DependencyProperty.Register("CheckChangedCommand", typeof(ICommand), typeof(ToggleSwitch), new PropertyMetadata(null)); + public static readonly DependencyProperty CheckedCommandProperty = DependencyProperty.Register("CheckedCommand", typeof(ICommand), typeof(ToggleSwitch), new PropertyMetadata(null)); + public static readonly DependencyProperty UnCheckedCommandProperty = DependencyProperty.Register("UnCheckedCommand", typeof(ICommand), typeof(ToggleSwitch), new PropertyMetadata(null)); + + public static readonly DependencyProperty CheckChangedCommandParameterProperty = DependencyProperty.Register("CheckChangedCommandParameter", typeof(object), typeof(ToggleSwitch), new PropertyMetadata(null)); + public static readonly DependencyProperty CheckedCommandParameterProperty = DependencyProperty.Register("CheckedCommandParameter", typeof(object), typeof(ToggleSwitch), new PropertyMetadata(null)); + public static readonly DependencyProperty UnCheckedCommandParameterProperty = DependencyProperty.Register("UnCheckedCommandParameter", typeof(object), typeof(ToggleSwitch), new PropertyMetadata(null)); + // LeftToRight means content left and button right and RightToLeft vise versa public static readonly DependencyProperty ContentDirectionProperty = DependencyProperty.Register("ContentDirection", typeof(FlowDirection), typeof(ToggleSwitch), new PropertyMetadata(FlowDirection.LeftToRight)); + public static readonly DependencyProperty ToggleSwitchButtonStyleProperty = DependencyProperty.Register("ToggleSwitchButtonStyle", typeof(Style), typeof(ToggleSwitch), new FrameworkPropertyMetadata(default(Style), FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure)); public event EventHandler Checked; public event EventHandler Unchecked; @@ -84,23 +103,76 @@ public DataTemplate HeaderTemplate /// /// Gets/sets the brush used for the switch's foreground. /// + [Obsolete(@"This property will be deleted in the next release. You should use OnSwitchBrush and OffSwitchBrush to change the switch's brushes.")] public Brush SwitchForeground { get { return (Brush)GetValue(SwitchForegroundProperty); } - set - { - SetValue(SwitchForegroundProperty, value); - } + set { SetValue(SwitchForegroundProperty, value); } + } + + /// + /// Gets/sets the brush used for the on-switch's foreground. + /// + public Brush OnSwitchBrush + { + get { return (Brush)GetValue(OnSwitchBrushProperty); } + set { SetValue(OnSwitchBrushProperty, value); } + } + + /// + /// Gets/sets the brush used for the off-switch's foreground. + /// + public Brush OffSwitchBrush + { + get { return (Brush)GetValue(OffSwitchBrushProperty); } + set { SetValue(OffSwitchBrushProperty, value); } + } + + /// + /// Gets/sets the brush used for the thumb indicator. + /// + public Brush ThumbIndicatorBrush + { + get { return (Brush)GetValue(ThumbIndicatorBrushProperty); } + set { SetValue(ThumbIndicatorBrushProperty, value); } + } + + /// + /// Gets/sets the brush used for the thumb indicator. + /// + public Brush ThumbIndicatorDisabledBrush + { + get { return (Brush)GetValue(ThumbIndicatorDisabledBrushProperty); } + set { SetValue(ThumbIndicatorDisabledBrushProperty, value); } + } + + /// + /// Gets/sets the width of the thumb indicator. + /// + public double ThumbIndicatorWidth + { + get { return (double)GetValue(ThumbIndicatorWidthProperty); } + set { SetValue(ThumbIndicatorWidthProperty, value); } } /// /// Gets/sets the control's content flow direction. /// - public FlowDirection ContentDirection { + public FlowDirection ContentDirection + { get { return (FlowDirection)GetValue(ContentDirectionProperty); } set { SetValue(ContentDirectionProperty, value); } } + /// + /// Gets/sets the control's toggle switch button style. + /// + public Style ToggleSwitchButtonStyle + { + get { return (Style)GetValue(ToggleSwitchButtonStyleProperty); } + set { SetValue(ToggleSwitchButtonStyleProperty, value); } + } + /// /// Gets/sets whether the control is Checked (On) or not (Off). /// @@ -111,6 +183,60 @@ public bool? IsChecked set { SetValue(IsCheckedProperty, value); } } + /// + /// Gets/sets the command which will be executed if the IsChecked property was changed. + /// + public ICommand CheckChangedCommand + { + get { return (ICommand)GetValue(CheckChangedCommandProperty); } + set { SetValue(CheckChangedCommandProperty, value); } + } + + /// + /// Gets/sets the command which will be executed if the checked event of the control is fired. + /// + public ICommand CheckedCommand + { + get { return (ICommand)GetValue(CheckedCommandProperty); } + set { SetValue(CheckedCommandProperty, value); } + } + + /// + /// Gets/sets the command which will be executed if the checked event of the control is fired. + /// + public ICommand UnCheckedCommand + { + get { return (ICommand)GetValue(UnCheckedCommandProperty); } + set { SetValue(UnCheckedCommandProperty, value); } + } + + /// + /// Gets/sets the command parameter which will be passed by the CheckChangedCommand. + /// + public object CheckChangedCommandParameter + { + get { return (object)GetValue(CheckChangedCommandParameterProperty); } + set { SetValue(CheckChangedCommandParameterProperty, value); } + } + + /// + /// Gets/sets the command parameter which will be passed by the CheckedCommand. + /// + public object CheckedCommandParameter + { + get { return (object)GetValue(CheckedCommandParameterProperty); } + set { SetValue(CheckedCommandParameterProperty, value); } + } + + /// + /// Gets/sets the command parameter which will be passed by the UnCheckedCommand. + /// + public object UnCheckedCommandParameter + { + get { return (object)GetValue(UnCheckedCommandParameterProperty); } + set { SetValue(UnCheckedCommandParameterProperty, value); } + } + /// /// An event that is raised when the value of IsChecked changes. /// @@ -124,9 +250,20 @@ private static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyCha var oldValue = (bool?)e.OldValue; var newValue = (bool?)e.NewValue; - if (oldValue != newValue && toggleSwitch.IsCheckedChanged != null) + if (oldValue != newValue) { - toggleSwitch.IsCheckedChanged(toggleSwitch, EventArgs.Empty); + var command = toggleSwitch.CheckChangedCommand; + var commandParameter = toggleSwitch.CheckChangedCommandParameter ?? toggleSwitch; + if (command != null && command.CanExecute(commandParameter)) + { + command.Execute(commandParameter); + } + + var eh = toggleSwitch.IsCheckedChanged; + if (eh != null) + { + eh(toggleSwitch, EventArgs.Empty); + } } } } @@ -136,18 +273,13 @@ public ToggleSwitch() DefaultStyleKey = typeof(ToggleSwitch); PreviewKeyUp += ToggleSwitch_PreviewKeyUp; + MouseUp += (sender, args) => Keyboard.Focus(this); } void ToggleSwitch_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == System.Windows.Input.Key.Space && e.OriginalSource == sender) - IsChecked = !IsChecked; - } - - private void SetDefaultContent() - { - Binding binding = new Binding("IsChecked") { Source = this, Converter = new OffOnConverter(), ConverterParameter = this }; - SetBinding(ContentProperty, binding); + IsChecked = !IsChecked; } private void ChangeVisualState(bool useTransitions) @@ -155,21 +287,10 @@ private void ChangeVisualState(bool useTransitions) VisualStateManager.GoToState(this, IsEnabled ? NormalState : DisabledState, useTransitions); } - protected override void OnContentChanged(object oldContent, object newContent) - { - base.OnContentChanged(oldContent, newContent); - _wasContentSet = true; - } - public override void OnApplyTemplate() { base.OnApplyTemplate(); - if (!_wasContentSet && GetBindingExpression(ContentProperty) == null) - { - SetDefaultContent(); - } - if (_toggleButton != null) { _toggleButton.Checked -= CheckedHandler; @@ -179,6 +300,8 @@ public override void OnApplyTemplate() BindingOperations.ClearBinding(_toggleButton, ToggleButton.IsCheckedProperty); _toggleButton.IsEnabledChanged -= IsEnabledHandler; + + _toggleButton.PreviewMouseUp -= this.ToggleButtonPreviewMouseUp; } _toggleButton = GetTemplateChild(SwitchPart) as ToggleButton; if (_toggleButton != null) @@ -191,10 +314,17 @@ public override void OnApplyTemplate() _toggleButton.SetBinding(ToggleButton.IsCheckedProperty, binding); _toggleButton.IsEnabledChanged += IsEnabledHandler; + + _toggleButton.PreviewMouseUp += this.ToggleButtonPreviewMouseUp; } ChangeVisualState(false); } + private void ToggleButtonPreviewMouseUp(object sender, MouseButtonEventArgs e) + { + Keyboard.Focus(this); + } + private void IsEnabledHandler(object sender, DependencyPropertyChangedEventArgs e) { ChangeVisualState(false); @@ -202,11 +332,25 @@ private void IsEnabledHandler(object sender, DependencyPropertyChangedEventArgs private void CheckedHandler(object sender, RoutedEventArgs e) { + var command = this.CheckedCommand; + var commandParameter = this.CheckedCommandParameter ?? this; + if (command != null && command.CanExecute(commandParameter)) + { + command.Execute(commandParameter); + } + SafeRaise.Raise(Checked, this, e); } private void UncheckedHandler(object sender, RoutedEventArgs e) { + var command = this.UnCheckedCommand; + var commandParameter = this.UnCheckedCommandParameter ?? this; + if (command != null && command.CanExecute(commandParameter)) + { + command.Execute(commandParameter); + } + SafeRaise.Raise(Unchecked, this, e); } diff --git a/MahApps.Metro/Controls/ToggleSwitchButton.cs b/MahApps.Metro/Controls/ToggleSwitchButton.cs index b17e51ddf2..ded738e9c2 100644 --- a/MahApps.Metro/Controls/ToggleSwitchButton.cs +++ b/MahApps.Metro/Controls/ToggleSwitchButton.cs @@ -31,20 +31,68 @@ public class ToggleSwitchButton : ToggleButton private Rectangle _ThumbIndicator; private TranslateTransform _ThumbTranslate; - public static readonly DependencyProperty SwitchForegroundProperty = DependencyProperty.Register("SwitchForeground", typeof(Brush), typeof(ToggleSwitchButton), new PropertyMetadata(null)); + [Obsolete(@"This property will be deleted in the next release. You should use OnSwitchBrush and OffSwitchBrush to change the switch's brushes.")] + public static readonly DependencyProperty SwitchForegroundProperty = DependencyProperty.Register("SwitchForeground", typeof(Brush), typeof(ToggleSwitchButton), new PropertyMetadata(null, (o, e) => ((ToggleSwitchButton)o).OnSwitchBrush = e.NewValue as Brush)); + public static readonly DependencyProperty OnSwitchBrushProperty = DependencyProperty.Register("OnSwitchBrush", typeof(Brush), typeof(ToggleSwitchButton), null); + public static readonly DependencyProperty OffSwitchBrushProperty = DependencyProperty.Register("OffSwitchBrush", typeof(Brush), typeof(ToggleSwitchButton), null); + + public static readonly DependencyProperty ThumbIndicatorBrushProperty = DependencyProperty.Register("ThumbIndicatorBrush", typeof(Brush), typeof(ToggleSwitchButton), null); + public static readonly DependencyProperty ThumbIndicatorDisabledBrushProperty = DependencyProperty.Register("ThumbIndicatorDisabledBrush", typeof(Brush), typeof(ToggleSwitchButton), null); + public static readonly DependencyProperty ThumbIndicatorWidthProperty = DependencyProperty.Register("ThumbIndicatorWidth", typeof(double), typeof(ToggleSwitchButton), new PropertyMetadata(13d)); + /// /// Gets/sets the brush used for the control's foreground. /// + [Obsolete(@"This property will be deleted in the next release. You should use OnSwitchBrush and OffSwitchBrush to change the switch's brushes.")] public Brush SwitchForeground { - get - { - return (Brush)GetValue(SwitchForegroundProperty); - } - set - { - SetValue(SwitchForegroundProperty, value); - } + get { return (Brush)GetValue(SwitchForegroundProperty); } + set { SetValue(SwitchForegroundProperty, value); } + } + + /// + /// Gets/sets the brush used for the on-switch's foreground. + /// + public Brush OnSwitchBrush + { + get { return (Brush)GetValue(OnSwitchBrushProperty); } + set { SetValue(OnSwitchBrushProperty, value); } + } + + /// + /// Gets/sets the brush used for the off-switch's foreground. + /// + public Brush OffSwitchBrush + { + get { return (Brush)GetValue(OffSwitchBrushProperty); } + set { SetValue(OffSwitchBrushProperty, value); } + } + + /// + /// Gets/sets the brush used for the thumb indicator. + /// + public Brush ThumbIndicatorBrush + { + get { return (Brush)GetValue(ThumbIndicatorBrushProperty); } + set { SetValue(ThumbIndicatorBrushProperty, value); } + } + + /// + /// Gets/sets the brush used for the thumb indicator. + /// + public Brush ThumbIndicatorDisabledBrush + { + get { return (Brush)GetValue(ThumbIndicatorDisabledBrushProperty); } + set { SetValue(ThumbIndicatorDisabledBrushProperty, value); } + } + + /// + /// Gets/sets the width of the thumb indicator. + /// + public double ThumbIndicatorWidth + { + get { return (double)GetValue(ThumbIndicatorWidthProperty); } + set { SetValue(ThumbIndicatorWidthProperty, value); } } public ToggleSwitchButton() @@ -73,14 +121,13 @@ private void UpdateThumb() _thumbAnimation.FillBehavior = FillBehavior.Stop; AnimationTimeline currentAnimation = _thumbAnimation; - _thumbAnimation.Completed += (sender, e) => + _thumbAnimation.Completed += (sender, e) => { + if (_thumbAnimation != null && currentAnimation == _thumbAnimation) { - if (_thumbAnimation != null && currentAnimation == _thumbAnimation) - { - _ThumbTranslate.X = destination; - _thumbAnimation = null; - } - }; + _ThumbTranslate.X = destination; + _thumbAnimation = null; + } + }; _ThumbTranslate.BeginAnimation(TranslateTransform.XProperty, _thumbAnimation); } } diff --git a/MahApps.Metro/Converters/OffOnConverter.cs b/MahApps.Metro/Converters/OffOnConverter.cs index da2e12a782..fa5eb77456 100644 --- a/MahApps.Metro/Converters/OffOnConverter.cs +++ b/MahApps.Metro/Converters/OffOnConverter.cs @@ -6,6 +6,7 @@ namespace MahApps.Metro.Converters { + [Obsolete(@"This converter will be deleted in the next release.")] public class OffOnConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) diff --git a/MahApps.Metro/Styles/Controls.Buttons.xaml b/MahApps.Metro/Styles/Controls.Buttons.xaml index 9e494a8544..ee3ffbb234 100644 --- a/MahApps.Metro/Styles/Controls.Buttons.xaml +++ b/MahApps.Metro/Styles/Controls.Buttons.xaml @@ -803,6 +803,115 @@ + + -