diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs index 5d9000b..b0eaf2f 100644 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -8,6 +8,7 @@ public static class MenuKeys public const string MenuKeyButtonGroup = "ButtonGroup"; public const string MenuKeyDivider = "Divider"; public const string MenuKeyDualBadge = "DualBadge"; + public const string MenuKeyEnumSelector = "EnumSelector"; public const string MenuKeyImageViewer = "ImageViewer"; public const string MenuKeyIpBox = "IPv4Box"; public const string MenuKeyIconButton = "IconButton"; diff --git a/demo/Ursa.Demo/Pages/EnumSelectorDemo.axaml b/demo/Ursa.Demo/Pages/EnumSelectorDemo.axaml new file mode 100644 index 0000000..2105b49 --- /dev/null +++ b/demo/Ursa.Demo/Pages/EnumSelectorDemo.axaml @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/EnumSelectorDemo.axaml.cs b/demo/Ursa.Demo/Pages/EnumSelectorDemo.axaml.cs new file mode 100644 index 0000000..da6250a --- /dev/null +++ b/demo/Ursa.Demo/Pages/EnumSelectorDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class EnumSelectorDemo : UserControl +{ + public EnumSelectorDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/EnumSelectorDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/EnumSelectorDemoViewModel.cs new file mode 100644 index 0000000..20d3297 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/EnumSelectorDemoViewModel.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.ObjectModel; +using Avalonia.Animation; +using Avalonia.Controls; +using Avalonia.Data; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Layout; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public class EnumSelectorDemoViewModel: ObservableObject +{ + public ObservableCollection Types { get; set; } + + private Type? _selectedType; + 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() + { + typeof(HorizontalAlignment), + typeof(VerticalAlignment), + typeof(Orientation), + typeof(Dock), + typeof(GridResizeDirection), + typeof(DayOfWeek), + typeof(FillMode), + typeof(IterationType), + typeof(BindingMode), + typeof(BindingPriority), + typeof(StandardCursorType), + typeof(Key), + typeof(KeyModifiers), + typeof(RoutingStrategies), + }; + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index fbcee7c..8ebf182 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -30,6 +30,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyButtonGroup => new ButtonGroupDemoViewModel(), MenuKeys.MenuKeyDivider => new DividerDemoViewModel(), MenuKeys.MenuKeyDualBadge => new DualBadgeDemoViewModel(), + MenuKeys.MenuKeyEnumSelector => new EnumSelectorDemoViewModel(), MenuKeys.MenuKeyImageViewer => new ImageViewerDemoViewModel(), MenuKeys.MenuKeyIconButton => new IconButtonDemoViewModel(), MenuKeys.MenuKeyIpBox => new IPv4BoxDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index a938dc4..d3335cb 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -17,6 +17,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "ButtonGroup", Key = MenuKeys.MenuKeyButtonGroup }, new() { MenuHeader = "Divider", Key = MenuKeys.MenuKeyDivider }, new() { MenuHeader = "DualBadge", Key = MenuKeys.MenuKeyDualBadge }, + new() { MenuHeader = "Enum Selector", Key = MenuKeys.MenuKeyEnumSelector }, new() { MenuHeader = "IconButton", Key = MenuKeys.MenuKeyIconButton }, new() { MenuHeader = "ImageViewer", Key = MenuKeys.MenuKeyImageViewer }, new() { MenuHeader = "IPv4Box", Key = MenuKeys.MenuKeyIpBox }, diff --git a/src/Ursa.Themes.Semi/Controls/EnumSelector.axaml b/src/Ursa.Themes.Semi/Controls/EnumSelector.axaml new file mode 100644 index 0000000..064d1a7 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/EnumSelector.axaml @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index 3417acc..9f871de 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -6,6 +6,7 @@ + diff --git a/src/Ursa/Controls/EnumSelector/EnumSelector.cs b/src/Ursa/Controls/EnumSelector/EnumSelector.cs new file mode 100644 index 0000000..4acdfcb --- /dev/null +++ b/src/Ursa/Controls/EnumSelector/EnumSelector.cs @@ -0,0 +1,67 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Data; + +namespace Ursa.Controls; + +public class EnumSelector: TemplatedControl +{ + public static readonly StyledProperty EnumTypeProperty = AvaloniaProperty.Register( + nameof(EnumType), validate: OnTypeValidate); + + public Type? EnumType + { + get => GetValue(EnumTypeProperty); + set => SetValue(EnumTypeProperty, value); + } + + private static bool OnTypeValidate(Type? arg) + { + if (arg is null) return true; + return arg.IsEnum; + } + + public static readonly StyledProperty ValueProperty = AvaloniaProperty.Register( + nameof(Value), defaultBindingMode: BindingMode.TwoWay); + + public object? Value + { + get => GetValue(ValueProperty); + set => SetValue(ValueProperty, value); + } + + public static readonly DirectProperty?> ValuesProperty = AvaloniaProperty.RegisterDirect?>( + nameof(Values), o => o.Values); + + private IList? _values; + internal IList? Values + { + get => _values; + private set => SetAndRaise(ValuesProperty, ref _values, value); + } + + + static EnumSelector() + { + EnumTypeProperty.Changed.AddClassHandler((o, e) => o.OnTypeChanged(e)); + } + + private void OnTypeChanged(AvaloniaPropertyChangedEventArgs args) + { + var newType = args.GetNewValue(); + if (newType is null || !newType.IsEnum) + { + return; + } + + var values = Enum.GetValues(newType); + List list = new(); + foreach (var value in values) + { + if (value.GetType() == newType) + list.Add(value); + } + Values = list; + } +} \ No newline at end of file