csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.6 KiB
115 lines
3.6 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Linq;
|
|
using Avalonia.Automation.Peers;
|
|
using Avalonia.Controls.Automation.Peers;
|
|
using Avalonia.Controls.Primitives;
|
|
using Avalonia.Reactive;
|
|
using Avalonia.Rendering;
|
|
using Avalonia.VisualTree;
|
|
|
|
namespace Avalonia.Controls
|
|
{
|
|
/// <summary>
|
|
/// Represents a button that allows a user to select a single option from a group of options.
|
|
/// </summary>
|
|
public class RadioButton : ToggleButton, IRadioButton
|
|
{
|
|
/// <summary>
|
|
/// Identifies the GroupName dependency property.
|
|
/// </summary>
|
|
public static readonly StyledProperty<string?> GroupNameProperty =
|
|
AvaloniaProperty.Register<RadioButton, string?>(nameof(GroupName));
|
|
|
|
private RadioButtonGroupManager? _groupManager;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name that specifies which RadioButton controls are mutually exclusive.
|
|
/// </summary>
|
|
public string? GroupName
|
|
{
|
|
get => GetValue(GroupNameProperty);
|
|
set => SetValue(GroupNameProperty, value);
|
|
}
|
|
|
|
bool IRadioButton.IsChecked
|
|
{
|
|
get => IsChecked.GetValueOrDefault();
|
|
set => SetCurrentValue(IsCheckedProperty, value);
|
|
}
|
|
|
|
MenuItemToggleType IRadioButton.ToggleType => MenuItemToggleType.Radio;
|
|
|
|
protected override void Toggle()
|
|
{
|
|
if (!IsChecked.GetValueOrDefault())
|
|
{
|
|
SetCurrentValue(IsCheckedProperty, true);
|
|
}
|
|
}
|
|
|
|
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
|
|
{
|
|
_groupManager?.Remove(this, GroupName);
|
|
EnsureRadioGroupManager(e.Root);
|
|
base.OnAttachedToVisualTree(e);
|
|
}
|
|
|
|
protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
|
|
{
|
|
base.OnDetachedFromVisualTree(e);
|
|
|
|
_groupManager?.Remove(this, GroupName);
|
|
_groupManager = null;
|
|
}
|
|
|
|
protected override AutomationPeer OnCreateAutomationPeer()
|
|
{
|
|
return new RadioButtonAutomationPeer(this);
|
|
}
|
|
|
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
|
{
|
|
base.OnPropertyChanged(change);
|
|
|
|
if (change.Property == IsCheckedProperty)
|
|
{
|
|
IsCheckedChanged(change.GetNewValue<bool?>());
|
|
}
|
|
else if (change.Property == GroupNameProperty)
|
|
{
|
|
var (oldValue, newValue) = change.GetOldAndNewValue<string?>();
|
|
OnGroupNameChanged(oldValue, newValue);
|
|
}
|
|
}
|
|
|
|
private void OnGroupNameChanged(string? oldGroupName, string? newGroupName)
|
|
{
|
|
if (!string.IsNullOrEmpty(oldGroupName))
|
|
{
|
|
_groupManager?.Remove(this, oldGroupName);
|
|
}
|
|
if (!string.IsNullOrEmpty(newGroupName))
|
|
{
|
|
EnsureRadioGroupManager();
|
|
}
|
|
}
|
|
|
|
private new void IsCheckedChanged(bool? value)
|
|
{
|
|
if (value.GetValueOrDefault())
|
|
{
|
|
EnsureRadioGroupManager();
|
|
_groupManager.OnCheckedChanged(this);
|
|
}
|
|
}
|
|
|
|
[MemberNotNull(nameof(_groupManager))]
|
|
private void EnsureRadioGroupManager(IRenderRoot? root = null)
|
|
{
|
|
_groupManager = RadioButtonGroupManager.GetOrCreateForRoot(root ?? this.GetVisualRoot());
|
|
_groupManager.Add(this);
|
|
}
|
|
}
|
|
}
|
|
|