|
|
|
@ -7,8 +7,14 @@ using Avalonia.Data; |
|
|
|
|
|
|
|
namespace Avalonia.Controls.Primitives |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// Represents a control that a user can select (check) or clear (uncheck). Base class for controls that can switch states.
|
|
|
|
/// </summary>
|
|
|
|
public class ToggleButton : Button |
|
|
|
{ |
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="IsChecked"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly DirectProperty<ToggleButton, bool?> IsCheckedProperty = |
|
|
|
AvaloniaProperty.RegisterDirect<ToggleButton, bool?>( |
|
|
|
nameof(IsChecked), |
|
|
|
@ -17,9 +23,30 @@ namespace Avalonia.Controls.Primitives |
|
|
|
unsetValue: null, |
|
|
|
defaultBindingMode: BindingMode.TwoWay); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="IsThreeState"/> property.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly StyledProperty<bool> IsThreeStateProperty = |
|
|
|
AvaloniaProperty.Register<ToggleButton, bool>(nameof(IsThreeState)); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="Checked"/> event.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly RoutedEvent<RoutedEventArgs> CheckedEvent = |
|
|
|
RoutedEvent.Register<ToggleButton, RoutedEventArgs>(nameof(Checked), RoutingStrategies.Bubble); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="Unchecked"/> event.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly RoutedEvent<RoutedEventArgs> UncheckedEvent = |
|
|
|
RoutedEvent.Register<ToggleButton, RoutedEventArgs>(nameof(Unchecked), RoutingStrategies.Bubble); |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Defines the <see cref="Unchecked"/> event.
|
|
|
|
/// </summary>
|
|
|
|
public static readonly RoutedEvent<RoutedEventArgs> IndeterminateEvent = |
|
|
|
RoutedEvent.Register<ToggleButton, RoutedEventArgs>(nameof(Indeterminate), RoutingStrategies.Bubble); |
|
|
|
|
|
|
|
private bool? _isChecked = false; |
|
|
|
|
|
|
|
static ToggleButton() |
|
|
|
@ -27,14 +54,49 @@ namespace Avalonia.Controls.Primitives |
|
|
|
PseudoClass<ToggleButton, bool?>(IsCheckedProperty, c => c == true, ":checked"); |
|
|
|
PseudoClass<ToggleButton, bool?>(IsCheckedProperty, c => c == false, ":unchecked"); |
|
|
|
PseudoClass<ToggleButton, bool?>(IsCheckedProperty, c => c == null, ":indeterminate"); |
|
|
|
|
|
|
|
IsCheckedProperty.Changed.AddClassHandler<ToggleButton>((x, e) => x.OnIsCheckedChanged(e)); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raised when a <see cref="ToggleButton"/> is checked.
|
|
|
|
/// </summary>
|
|
|
|
public event EventHandler<RoutedEventArgs> Checked |
|
|
|
{ |
|
|
|
add => AddHandler(CheckedEvent, value); |
|
|
|
remove => RemoveHandler(CheckedEvent, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raised when a <see cref="ToggleButton"/> is unchecked.
|
|
|
|
/// </summary>
|
|
|
|
public event EventHandler<RoutedEventArgs> Unchecked |
|
|
|
{ |
|
|
|
add => AddHandler(UncheckedEvent, value); |
|
|
|
remove => RemoveHandler(UncheckedEvent, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Raised when a <see cref="ToggleButton"/> is neither checked nor unchecked.
|
|
|
|
/// </summary>
|
|
|
|
public event EventHandler<RoutedEventArgs> Indeterminate |
|
|
|
{ |
|
|
|
add => AddHandler(IndeterminateEvent, value); |
|
|
|
remove => RemoveHandler(IndeterminateEvent, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets whether the <see cref="ToggleButton"/> is checked.
|
|
|
|
/// </summary>
|
|
|
|
public bool? IsChecked |
|
|
|
{ |
|
|
|
get { return _isChecked; } |
|
|
|
set { SetAndRaise(IsCheckedProperty, ref _isChecked, value); } |
|
|
|
get => _isChecked; |
|
|
|
set => SetAndRaise(IsCheckedProperty, ref _isChecked, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a value that indicates whether the control supports three states.
|
|
|
|
/// </summary>
|
|
|
|
public bool IsThreeState |
|
|
|
{ |
|
|
|
get => GetValue(IsThreeStateProperty); |
|
|
|
@ -47,18 +109,78 @@ namespace Avalonia.Controls.Primitives |
|
|
|
base.OnClick(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Toggles the <see cref="IsChecked"/> property.
|
|
|
|
/// </summary>
|
|
|
|
protected virtual void Toggle() |
|
|
|
{ |
|
|
|
if (IsChecked.HasValue) |
|
|
|
{ |
|
|
|
if (IsChecked.Value) |
|
|
|
{ |
|
|
|
if (IsThreeState) |
|
|
|
{ |
|
|
|
IsChecked = null; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
IsChecked = false; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
IsChecked = true; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
IsChecked = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when <see cref="IsChecked"/> becomes true.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="e">Event arguments for the routed event that is raised by the default implementation of this method.</param>
|
|
|
|
protected virtual void OnChecked(RoutedEventArgs e) |
|
|
|
{ |
|
|
|
RaiseEvent(e); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when <see cref="IsChecked"/> becomes false.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="e">Event arguments for the routed event that is raised by the default implementation of this method.</param>
|
|
|
|
protected virtual void OnUnchecked(RoutedEventArgs e) |
|
|
|
{ |
|
|
|
RaiseEvent(e); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Called when <see cref="IsChecked"/> becomes null.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="e">Event arguments for the routed event that is raised by the default implementation of this method.</param>
|
|
|
|
protected virtual void OnIndeterminate(RoutedEventArgs e) |
|
|
|
{ |
|
|
|
RaiseEvent(e); |
|
|
|
} |
|
|
|
|
|
|
|
private void OnIsCheckedChanged(AvaloniaPropertyChangedEventArgs e) |
|
|
|
{ |
|
|
|
var newValue = (bool?)e.NewValue; |
|
|
|
|
|
|
|
switch (newValue) |
|
|
|
{ |
|
|
|
case true: |
|
|
|
OnChecked(new RoutedEventArgs(CheckedEvent)); |
|
|
|
break; |
|
|
|
case false: |
|
|
|
OnUnchecked(new RoutedEventArgs(UncheckedEvent)); |
|
|
|
break; |
|
|
|
default: |
|
|
|
OnIndeterminate(new RoutedEventArgs(IndeterminateEvent)); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|