From a574fb76b42a69f88d458ba0748806abfd7b14d5 Mon Sep 17 00:00:00 2001 From: rabbitism Date: Sat, 17 Feb 2024 21:10:24 +0800 Subject: [PATCH] feat: add temp template. --- demo/Ursa.Demo/Models/MenuKeys.cs | 1 + demo/Ursa.Demo/Pages/FormDemo.axaml | 27 ++++++++++++ demo/Ursa.Demo/Pages/FormDemo.axaml.cs | 13 ++++++ .../Ursa.Demo/ViewModels/FormDemoViewModel.cs | 43 +++++++++++++++++++ .../Ursa.Demo/ViewModels/MainViewViewModel.cs | 1 + demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 1 + src/Ursa.Themes.Semi/Controls/Form.axaml | 34 +++++++++++++++ src/Ursa.Themes.Semi/Controls/_index.axaml | 1 + src/Ursa/Controls/Form/Form.cs | 33 ++++++++------ src/Ursa/Controls/Form/FormGroup.cs | 16 ++++++- src/Ursa/Controls/Form/FormItem.cs | 23 +++++++++- src/Ursa/Controls/Form/IFormItem.cs | 9 ---- 12 files changed, 176 insertions(+), 26 deletions(-) create mode 100644 demo/Ursa.Demo/Pages/FormDemo.axaml create mode 100644 demo/Ursa.Demo/Pages/FormDemo.axaml.cs create mode 100644 demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs create mode 100644 src/Ursa.Themes.Semi/Controls/Form.axaml delete mode 100644 src/Ursa/Controls/Form/IFormItem.cs diff --git a/demo/Ursa.Demo/Models/MenuKeys.cs b/demo/Ursa.Demo/Models/MenuKeys.cs index 56e6a49..6d32b0f 100644 --- a/demo/Ursa.Demo/Models/MenuKeys.cs +++ b/demo/Ursa.Demo/Models/MenuKeys.cs @@ -12,6 +12,7 @@ public static class MenuKeys public const string MenuKeyDrawer = "Drawer"; public const string MenuKeyDualBadge = "DualBadge"; public const string MenuKeyEnumSelector = "EnumSelector"; + public const string MenuKeyForm = "Form"; public const string MenuKeyImageViewer = "ImageViewer"; public const string MenuKeyIpBox = "IPv4Box"; public const string MenuKeyIconButton = "IconButton"; diff --git a/demo/Ursa.Demo/Pages/FormDemo.axaml b/demo/Ursa.Demo/Pages/FormDemo.axaml new file mode 100644 index 0000000..31642d9 --- /dev/null +++ b/demo/Ursa.Demo/Pages/FormDemo.axaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/FormDemo.axaml.cs b/demo/Ursa.Demo/Pages/FormDemo.axaml.cs new file mode 100644 index 0000000..64a5f0c --- /dev/null +++ b/demo/Ursa.Demo/Pages/FormDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class FormDemo : UserControl +{ + public FormDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs new file mode 100644 index 0000000..4e354a1 --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs @@ -0,0 +1,43 @@ +using System; +using System.ComponentModel.DataAnnotations; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public partial class FormDemoViewModel: ObservableObject +{ + [ObservableProperty] private DataModel _model; + + public FormDemoViewModel() + { + Model = new DataModel(); + } +} + +public partial class DataModel : ObservableObject +{ + private string _name; + + [MinLength(10)] + public string Name + { + get=>_name; + set => SetProperty(ref _name, value); + } + + private string _email; + + [EmailAddress] + public string Email + { + get=>_email; + set => SetProperty(ref _email, value); + } + + private DateTime _date; + public DateTime Date + { + get => _date; + set => SetProperty(ref _date, value); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 43166bd..6ce81d0 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -34,6 +34,7 @@ public class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyDrawer => new DrawerDemoViewModel(), MenuKeys.MenuKeyDualBadge => new DualBadgeDemoViewModel(), MenuKeys.MenuKeyEnumSelector => new EnumSelectorDemoViewModel(), + MenuKeys.MenuKeyForm => new FormDemoViewModel(), 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 6f6da25..6900d73 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -21,6 +21,7 @@ public class MenuViewModel: ViewModelBase new() { MenuHeader = "Drawer", Key = MenuKeys.MenuKeyDrawer }, new() { MenuHeader = "DualBadge", Key = MenuKeys.MenuKeyDualBadge }, new() { MenuHeader = "Enum Selector", Key = MenuKeys.MenuKeyEnumSelector }, + new() { MenuHeader = "Form", Key = MenuKeys.MenuKeyForm }, new() { MenuHeader = "Icon Button", Key = MenuKeys.MenuKeyIconButton }, new() { MenuHeader = "ImageViewer", Key = MenuKeys.MenuKeyImageViewer }, new() { MenuHeader = "IPv4Box", Key = MenuKeys.MenuKeyIpBox }, diff --git a/src/Ursa.Themes.Semi/Controls/Form.axaml b/src/Ursa.Themes.Semi/Controls/Form.axaml new file mode 100644 index 0000000..eb03889 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/Form.axaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/_index.axaml b/src/Ursa.Themes.Semi/Controls/_index.axaml index 0b2dae5..40c4a53 100644 --- a/src/Ursa.Themes.Semi/Controls/_index.axaml +++ b/src/Ursa.Themes.Semi/Controls/_index.axaml @@ -11,6 +11,7 @@ + diff --git a/src/Ursa/Controls/Form/Form.cs b/src/Ursa/Controls/Form/Form.cs index 85260fa..4da0054 100644 --- a/src/Ursa/Controls/Form/Form.cs +++ b/src/Ursa/Controls/Form/Form.cs @@ -1,25 +1,32 @@ using Avalonia; -using Avalonia.Collections; using Avalonia.Controls; -using Avalonia.Markup.Xaml.Templates; -using Avalonia.Metadata; namespace Ursa.Controls; public class Form: ItemsControl { - - public static readonly StyledProperty> ItemsProperty = AvaloniaProperty.Register>( - "Items"); + public static readonly AttachedProperty LabelProperty = + AvaloniaProperty.RegisterAttached("Label"); + public static void SetLabel(Control obj, string value) => obj.SetValue(LabelProperty, value); + public static string GetLabel(Control obj) => obj.GetValue(LabelProperty); - public AvaloniaList Items - { - get => GetValue(ItemsProperty); - set => SetValue(ItemsProperty, value); - } - public void AddChild(object child) + public static readonly AttachedProperty IsRequiredProperty = + AvaloniaProperty.RegisterAttached("IsRequired"); + public static void SetIsRequired(Control obj, bool value) => obj.SetValue(IsRequiredProperty, value); + public static bool GetIsRequired(Control obj) => obj.GetValue(IsRequiredProperty); + + protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) { - throw new NotImplementedException(); + recycleKey = null; + return item is FormItem or FormGroup; + } + + protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey) + { + if (item is not Control control) return new FormItem(); + string label = GetLabel(control); + bool isRequired = GetIsRequired(control); + return new FormItem() { Label = label, IsRequired = isRequired, Content = control }; } } \ No newline at end of file diff --git a/src/Ursa/Controls/Form/FormGroup.cs b/src/Ursa/Controls/Form/FormGroup.cs index 0ed7f17..97a5e48 100644 --- a/src/Ursa/Controls/Form/FormGroup.cs +++ b/src/Ursa/Controls/Form/FormGroup.cs @@ -3,7 +3,19 @@ using Avalonia.Controls.Primitives; namespace Ursa.Controls; -public class FormGroup: HeaderedItemsControl, IFormItem +public class FormGroup: HeaderedItemsControl { - + protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) + { + recycleKey = null; + return item is not FormItem or FormGroup; + } + + protected override Control CreateContainerForItemOverride(object? item, int index, object? recycleKey) + { + if (item is not Control control) return new FormItem(); + var label = Form.GetLabel(control); + var isRequired = Form.GetIsRequired(control); + return new FormItem() { Label = label, IsRequired = isRequired, Content = control }; + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Form/FormItem.cs b/src/Ursa/Controls/Form/FormItem.cs index 374ea49..47a68bc 100644 --- a/src/Ursa/Controls/Form/FormItem.cs +++ b/src/Ursa/Controls/Form/FormItem.cs @@ -1,8 +1,27 @@ -using Avalonia.Controls.Primitives; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; namespace Ursa.Controls; -public class FormItem: TemplatedControl, IFormItem +public class FormItem: ContentControl { + public static readonly StyledProperty LabelProperty = AvaloniaProperty.Register( + nameof(Label)); + + public string Label + { + get => GetValue(LabelProperty); + set => SetValue(LabelProperty, value); + } + + public static readonly StyledProperty IsRequiredProperty = AvaloniaProperty.Register( + nameof(IsRequired)); + + public bool IsRequired + { + get => GetValue(IsRequiredProperty); + set => SetValue(IsRequiredProperty, value); + } } \ No newline at end of file diff --git a/src/Ursa/Controls/Form/IFormItem.cs b/src/Ursa/Controls/Form/IFormItem.cs deleted file mode 100644 index 1e726a9..0000000 --- a/src/Ursa/Controls/Form/IFormItem.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Controls.Primitives; - -namespace Ursa.Controls; - -public interface IFormItem -{ - -} \ No newline at end of file