Merge pull request #671 from irihitech/enum

Ensure initial state is respected in EnumSelector
This commit is contained in:
Zhang Dian
2025-05-30 14:22:59 +08:00
committed by GitHub
4 changed files with 51 additions and 46 deletions

View File

@@ -26,7 +26,7 @@
EnumType="{Binding SelectedType}" EnumType="{Binding SelectedType}"
Value="{Binding Value}" /> Value="{Binding Value}" />
<TextBlock Text="{Binding Value}" /> <TextBlock Text="{Binding Value}" />
<u:Divider Content="Small Size"></u:Divider> <u:Divider Content="Small Size" />
<u:EnumSelector <u:EnumSelector
Width="200" Width="200"
Classes="Small" Classes="Small"

View File

@@ -11,32 +11,13 @@ using CommunityToolkit.Mvvm.ComponentModel;
namespace Ursa.Demo.ViewModels; namespace Ursa.Demo.ViewModels;
public class EnumSelectorDemoViewModel: ObservableObject public partial class EnumSelectorDemoViewModel : ObservableObject
{ {
public ObservableCollection<Type?> Types { get; set; } [ObservableProperty] private Type? _selectedType;
[ObservableProperty] private object? _value;
private Type? _selectedType; public ObservableCollection<Type?> Types { get; set; } =
public Type? SelectedType [
{
get => _selectedType;
set
{
SetProperty(ref _selectedType, value);
Value = null;
}
}
private object? _value;
public object? Value
{
get => _value;
set => SetProperty(ref _value, value);
}
public EnumSelectorDemoViewModel()
{
Types = new ObservableCollection<Type?>()
{
typeof(HorizontalAlignment), typeof(HorizontalAlignment),
typeof(VerticalAlignment), typeof(VerticalAlignment),
typeof(Orientation), typeof(Orientation),
@@ -51,15 +32,12 @@ public class EnumSelectorDemoViewModel: ObservableObject
typeof(Key), typeof(Key),
typeof(KeyModifiers), typeof(KeyModifiers),
typeof(RoutingStrategies), typeof(RoutingStrategies),
typeof(CustomEnum), typeof(CustomEnum)
}; ];
}
} }
public enum CustomEnum public enum CustomEnum
{ {
[Description("是")] [Description("是")] Yes,
Yes, [Description("否")] No,
[Description("否")]
No,
} }

View File

@@ -34,6 +34,7 @@ public class EnumSelector: TemplatedControl
private static object? OnValueCoerce(AvaloniaObject o, object? value) private static object? OnValueCoerce(AvaloniaObject o, object? value)
{ {
if (o is not EnumSelector selector) return null; if (o is not EnumSelector selector) return null;
if (!selector.IsInitialized) return value;
if (value is null) return null; if (value is null) return null;
if (value.GetType() != selector.EnumType) return null; if (value.GetType() != selector.EnumType) return null;
var first = selector.Values?.FirstOrDefault(a => Equals(a.Value, value)); var first = selector.Values?.FirstOrDefault(a => Equals(a.Value, value));
@@ -128,6 +129,8 @@ public class EnumSelector: TemplatedControl
return; return;
} }
Values = GenerateItemTuple(); Values = GenerateItemTuple();
var first = Values?.FirstOrDefault(a => Equals(a.Value, this.Value));
SetCurrentValue(SelectedValueProperty, first);
} }
// netstandard 2.0 does not support Enum.GetValuesAsUnderlyingType, which is used for native aot compilation // netstandard 2.0 does not support Enum.GetValuesAsUnderlyingType, which is used for native aot compilation

View File

@@ -0,0 +1,24 @@
using Avalonia.Controls;
using Avalonia.Headless.XUnit;
using Ursa.Controls;
namespace HeadlessTest.Ursa.Controls.EnumSelectorTests;
public class InitialStateTest
{
[AvaloniaFact]
public void Initial_State_Respected()
{
var window = new Window();
var selector = new EnumSelector()
{
Value = HorizontalPosition.Right,
EnumType = typeof(HorizontalPosition),
};
window.Content = selector;
window.Show();
Assert.Equal(HorizontalPosition.Right, selector.Value);
Assert.NotNull(selector.SelectedValue);
Assert.Equal(HorizontalPosition.Right, selector.SelectedValue?.Value);
}
}