diff --git a/demo/Ursa.Demo/Pages/FormDemo.axaml b/demo/Ursa.Demo/Pages/FormDemo.axaml index 31642d9..79d4dd8 100644 --- a/demo/Ursa.Demo/Pages/FormDemo.axaml +++ b/demo/Ursa.Demo/Pages/FormDemo.axaml @@ -9,10 +9,10 @@ x:CompileBindings="True" x:Class="Ursa.Demo.Pages.FormDemo"> - + - - + + diff --git a/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs index 4e354a1..5f706a0 100644 --- a/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/FormDemoViewModel.cs @@ -40,4 +40,9 @@ public partial class DataModel : ObservableObject get => _date; set => SetProperty(ref _date, value); } + + public DataModel() + { + Date = DateTime.Today; + } } \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/Form.axaml b/src/Ursa.Themes.Semi/Controls/Form.axaml index eb03889..397ddac 100644 --- a/src/Ursa.Themes.Semi/Controls/Form.axaml +++ b/src/Ursa.Themes.Semi/Controls/Form.axaml @@ -5,7 +5,9 @@ - + + + diff --git a/src/Ursa/Controls/Form/Form.cs b/src/Ursa/Controls/Form/Form.cs index 4da0054..207e88b 100644 --- a/src/Ursa/Controls/Form/Form.cs +++ b/src/Ursa/Controls/Form/Form.cs @@ -1,14 +1,17 @@ using Avalonia; using Avalonia.Controls; +using Ursa.Common; namespace Ursa.Controls; public class Form: ItemsControl { - 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); + #region Attached Properties + + public static readonly AttachedProperty LabelProperty = + AvaloniaProperty.RegisterAttached("Label"); + public static void SetLabel(Control obj, object? value) => obj.SetValue(LabelProperty, value); + public static object? GetLabel(Control obj) => obj.GetValue(LabelProperty); public static readonly AttachedProperty IsRequiredProperty = @@ -16,6 +19,37 @@ public class Form: ItemsControl public static void SetIsRequired(Control obj, bool value) => obj.SetValue(IsRequiredProperty, value); public static bool GetIsRequired(Control obj) => obj.GetValue(IsRequiredProperty); + public static readonly AttachedProperty LabelWidthProperty = + AvaloniaProperty.RegisterAttached("LabelWidth"); + + public static void SetLabelWidth(Control obj, GridLength value) => obj.SetValue(LabelWidthProperty, value); + public static GridLength GetLabelWidth(Control obj) => obj.GetValue(LabelWidthProperty); + + #endregion + + + public static readonly StyledProperty LabelPositionProperty = AvaloniaProperty.Register( + nameof(LabelPosition)); + /// + /// Only Left and Top work. + /// + public Position LabelPosition + { + get => GetValue(LabelPositionProperty); + set => SetValue(LabelPositionProperty, value); + } + + public static readonly StyledProperty LabelAlignmentProperty = AvaloniaProperty.Register( + nameof(LabelAlignment)); + /// + /// Only Left and Right work. + /// + public Position LabelAlignment + { + get => GetValue(LabelAlignmentProperty); + set => SetValue(LabelAlignmentProperty, value); + } + protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) { recycleKey = null; @@ -25,8 +59,30 @@ public class Form: ItemsControl 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 }; + return new FormItem() + { + Content = control, + [!LabelProperty] = control.GetObservable(Form.LabelProperty).ToBinding(), + [!IsRequiredProperty] = control.GetObservable(Form.IsRequiredProperty).ToBinding(), + }; + } + + protected override void PrepareContainerForItemOverride(Control container, object? item, int index) + { + base.PrepareContainerForItemOverride(container, item, index); + if (container is FormGroup group) + { + if (!group.IsSet(FormGroup.LabelWidthProperty)) + { + group[!LabelWidthProperty] = this.GetObservable(LabelWidthProperty).ToBinding(); + } + } + else if (container is FormItem formItem) + { + if(!formItem.IsSet(FormItem.LabelWidthProperty)) + { + formItem[!LabelWidthProperty] = this.GetObservable(LabelWidthProperty).ToBinding(); + } + } } } \ No newline at end of file diff --git a/src/Ursa/Controls/Form/FormGroup.cs b/src/Ursa/Controls/Form/FormGroup.cs index 97a5e48..1742b4d 100644 --- a/src/Ursa/Controls/Form/FormGroup.cs +++ b/src/Ursa/Controls/Form/FormGroup.cs @@ -1,21 +1,41 @@ -using Avalonia.Controls; +using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.Primitives; namespace Ursa.Controls; public class FormGroup: HeaderedItemsControl { + public static readonly StyledProperty LabelWidthProperty = Form.LabelWidthProperty.AddOwner(); + + public GridLength LabelWidth + { + get => GetValue(LabelWidthProperty); + set => SetValue(LabelWidthProperty, value); + } protected override bool NeedsContainerOverride(object? item, int index, out object? recycleKey) { recycleKey = null; - return item is not FormItem or FormGroup; + return item is not FormItem; } 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 }; + return new FormItem + { + Content = control, + [!FormItem.LabelProperty] = control.GetObservable(Form.LabelProperty).ToBinding(), + [!FormItem.IsRequiredProperty] = control.GetObservable(Form.IsRequiredProperty).ToBinding(), + }; + } + + protected override void PrepareContainerForItemOverride(Control container, object? item, int index) + { + base.PrepareContainerForItemOverride(container, item, index); + if (container is FormItem formItem) + { + formItem.LabelWidth = LabelWidth; + } } } \ No newline at end of file diff --git a/src/Ursa/Controls/Form/FormItem.cs b/src/Ursa/Controls/Form/FormItem.cs index 47a68bc..0bd3116 100644 --- a/src/Ursa/Controls/Form/FormItem.cs +++ b/src/Ursa/Controls/Form/FormItem.cs @@ -6,10 +6,10 @@ namespace Ursa.Controls; public class FormItem: ContentControl { - public static readonly StyledProperty LabelProperty = AvaloniaProperty.Register( + public static readonly StyledProperty LabelProperty = AvaloniaProperty.Register( nameof(Label)); - public string Label + public object? Label { get => GetValue(LabelProperty); set => SetValue(LabelProperty, value); @@ -23,5 +23,24 @@ public class FormItem: ContentControl get => GetValue(IsRequiredProperty); set => SetValue(IsRequiredProperty, value); } + + public static readonly StyledProperty LabelWidthProperty = AvaloniaProperty.Register( + nameof(LabelWidth)); + + public GridLength LabelWidth + { + get => GetValue(LabelWidthProperty); + set => SetValue(LabelWidthProperty, value); + } + static FormItem() + { + LabelWidthProperty.Changed.AddClassHandler((x, args) => x.LabelWidthChanged(args)); + } + + private void LabelWidthChanged(AvaloniaPropertyChangedEventArgs args) + { + GridLength? length = args.GetNewValue(); + + } } \ No newline at end of file