using System;
using System.ComponentModel;
using Avalonia.Automation.Peers;
using Avalonia.Controls.Metadata;
using Avalonia.Data;
using Avalonia.Interactivity;
namespace Avalonia.Controls.Primitives
{
///
/// Represents a control that a user can select (check) or clear (uncheck). Base class for controls that can switch states.
///
[PseudoClasses(":checked", ":unchecked", ":indeterminate")]
public class ToggleButton : Button
{
///
/// Defines the property.
///
public static readonly StyledProperty IsCheckedProperty =
AvaloniaProperty.Register(nameof(IsChecked), false,
defaultBindingMode: BindingMode.TwoWay);
///
/// Defines the property.
///
public static readonly StyledProperty IsThreeStateProperty =
AvaloniaProperty.Register(nameof(IsThreeState));
///
/// Defines the event.
///
public static readonly RoutedEvent IsCheckedChangedEvent =
RoutedEvent.Register(
nameof(IsCheckedChanged),
RoutingStrategies.Bubble);
static ToggleButton()
{
}
public ToggleButton()
{
UpdatePseudoClasses(IsChecked);
}
///
/// Raised when the property value changes.
///
public event EventHandler? IsCheckedChanged
{
add => AddHandler(IsCheckedChangedEvent, value);
remove => RemoveHandler(IsCheckedChangedEvent, value);
}
///
/// Gets or sets whether the is checked.
///
public bool? IsChecked
{
get => GetValue(IsCheckedProperty);
set => SetValue(IsCheckedProperty, value);
}
///
/// Gets or sets a value that indicates whether the control supports three states.
///
public bool IsThreeState
{
get => GetValue(IsThreeStateProperty);
set => SetValue(IsThreeStateProperty, value);
}
protected override void OnClick()
{
if (!IsEffectivelyEnabled)
{
return;
}
Toggle();
base.OnClick();
}
///
/// Toggles the property.
///
protected virtual void Toggle()
{
bool? newValue;
if (IsChecked.HasValue)
{
if (IsChecked.Value)
{
if (IsThreeState)
{
newValue = null;
}
else
{
newValue = false;
}
}
else
{
newValue = true;
}
}
else
{
newValue = false;
}
SetCurrentValue(IsCheckedProperty, newValue);
}
///
/// Called when changes.
///
/// Event arguments for the routed event that is raised by the default implementation of this method.
protected virtual void OnIsCheckedChanged(RoutedEventArgs e)
{
RaiseEvent(e);
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new ToggleButtonAutomationPeer(this);
}
///
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == IsCheckedProperty)
{
var newValue = change.GetNewValue();
UpdatePseudoClasses(newValue);
OnIsCheckedChanged(new RoutedEventArgs(IsCheckedChangedEvent));
}
}
private void UpdatePseudoClasses(bool? isChecked)
{
PseudoClasses.Set(":checked", isChecked == true);
PseudoClasses.Set(":unchecked", isChecked == false);
PseudoClasses.Set(":indeterminate", isChecked == null);
}
}
}