From 8292febbd992fc282ba1dc517c1b2fd4a202a788 Mon Sep 17 00:00:00 2001 From: "AI\\jvermeyl" Date: Mon, 3 Feb 2025 10:14:35 +0100 Subject: [PATCH 1/2] ListComponentBase : trigger fieldchanged on changes when control is multiple mode --- .../Components/List/ListComponentBase.razor.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/Core/Components/List/ListComponentBase.razor.cs b/src/Core/Components/List/ListComponentBase.razor.cs index fde99cb13b..dd866127dd 100644 --- a/src/Core/Components/List/ListComponentBase.razor.cs +++ b/src/Core/Components/List/ListComponentBase.razor.cs @@ -527,19 +527,8 @@ protected virtual async Task OnSelectedItemChangedHandlerAsync(TOption? item) { if (!Equals(item, SelectedOption)) { - var value = GetOptionValue(item); - - if (this is FluentListbox || - this is FluentCombobox || - (this is FluentSelect && Value is null)) - { - await base.ChangeHandlerAsync(new ChangeEventArgs() { Value = value }); - } - SelectedOption = item; - - //InternalValue = Value = value; - InternalValue = value; + InternalValue = GetOptionValue(item); await RaiseChangedEventsAsync(); } } @@ -562,6 +551,8 @@ protected virtual async Task RaiseChangedEventsAsync() await SelectedOptionChanged.InvokeAsync(SelectedOption); } } + + await base.ChangeHandlerAsync(new ChangeEventArgs() { Value = InternalValue }); } protected virtual async Task OnKeydownHandlerAsync(KeyboardEventArgs e) From 3107fd622437f5472cc689f768d3de689c6598ec Mon Sep 17 00:00:00 2001 From: "AI\\jvermeyl" Date: Mon, 3 Feb 2025 13:49:29 +0100 Subject: [PATCH 2/2] ListComponentBase : implement missing binding expressions --- ...crosoft.FluentUI.AspNetCore.Components.xml | 12 ++++++++ .../List/Autocomplete/AutocompletePage.razor | 6 ---- examples/Demo/Shared/SampleData/Starship.cs | 1 + .../List/ListComponentBase.razor.cs | 29 +++++++++++++++++-- 4 files changed, 39 insertions(+), 9 deletions(-) diff --git a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml index a62b243597..c161ee7262 100644 --- a/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml +++ b/examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml @@ -6209,6 +6209,12 @@ ⚠️ Only available when Multiple = false. + + + Gets or sets an expression that identifies the bound selected options. + ⚠️ Only available when Multiple = false. + + If true, the user can select multiple elements. @@ -6238,6 +6244,12 @@ ⚠️ Only available when Multiple = true. + + + Gets or sets an expression that identifies the bound selected options. + ⚠️ Only available when Multiple = true. + + diff --git a/examples/Demo/Shared/Pages/List/Autocomplete/AutocompletePage.razor b/examples/Demo/Shared/Pages/List/Autocomplete/AutocompletePage.razor index edb614c842..30e7ab4c84 100644 --- a/examples/Demo/Shared/Pages/List/Autocomplete/AutocompletePage.razor +++ b/examples/Demo/Shared/Pages/List/Autocomplete/AutocompletePage.razor @@ -6,12 +6,6 @@

Autocomplete

-
- @(new MarkupString(DemoNavProvider.EditFormOffIcon)) - The FluentAutocomplete component is not yet fully compatible with the EditForm and FluentEditForm elements. - Some functionalities, such as error messages, the requirement message or the validation messages are missing. -
-

Examples

diff --git a/examples/Demo/Shared/SampleData/Starship.cs b/examples/Demo/Shared/SampleData/Starship.cs index d633d51ffe..0275855318 100644 --- a/examples/Demo/Shared/SampleData/Starship.cs +++ b/examples/Demo/Shared/SampleData/Starship.cs @@ -20,6 +20,7 @@ public class Starship public string? Description { get; set; } [Required(ErrorMessage = "Countries are required")] + [MinLength(1, ErrorMessage = "Countries are required")] public IEnumerable? Countries { get; set; } [Required(ErrorMessage = "A classification is required")] diff --git a/src/Core/Components/List/ListComponentBase.razor.cs b/src/Core/Components/List/ListComponentBase.razor.cs index dd866127dd..271120f02d 100644 --- a/src/Core/Components/List/ListComponentBase.razor.cs +++ b/src/Core/Components/List/ListComponentBase.razor.cs @@ -3,6 +3,7 @@ // ------------------------------------------------------------------------ using System.Diagnostics.CodeAnalysis; +using System.Linq.Expressions; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Web; @@ -36,7 +37,7 @@ public abstract partial class ListComponentBase : FluentInputBase _internalListContext; - internal override bool FieldBound => Field is not null || ValueExpression is not null || ValueChanged.HasDelegate || SelectedOptionChanged.HasDelegate || SelectedOptionsChanged.HasDelegate; + internal override bool FieldBound => Field is not null || ValueExpression is not null || ValueChanged.HasDelegate || SelectedOptionChanged.HasDelegate || SelectedOptionExpression is not null || SelectedOptionsChanged.HasDelegate || SelectedOptionsExpression is not null; protected override async Task OnAfterRenderAsync(bool firstRender) { @@ -147,6 +148,13 @@ protected string? InternalValue [Parameter] public virtual EventCallback SelectedOptionChanged { get; set; } + /// + /// Gets or sets an expression that identifies the bound selected options. + /// ⚠️ Only available when Multiple = false. + /// + [Parameter] + public Expression>? SelectedOptionExpression { get; set; } + /// /// If true, the user can select multiple elements. /// ⚠️ Only available for the FluentSelect and FluentListbox components. @@ -181,6 +189,13 @@ protected string? InternalValue [Parameter] public virtual EventCallback?> SelectedOptionsChanged { get; set; } + /// + /// Gets or sets an expression that identifies the bound selected options. + /// ⚠️ Only available when Multiple = true. + /// + [Parameter] + public Expression>>? SelectedOptionsExpression { get; set; } + /// public ListComponentBase() { @@ -293,11 +308,19 @@ public override async Task SetParametersAsync(ParameterView parameters) if (!_hasInitializedParameters) { - if (SelectedOptionChanged.HasDelegate) + if (SelectedOptionExpression is not null) + { + FieldIdentifier = FieldIdentifier.Create(SelectedOptionExpression); + } + else if (SelectedOptionChanged.HasDelegate) { FieldIdentifier = FieldIdentifier.Create(() => SelectedOption); } - if (SelectedOptionsChanged.HasDelegate) + else if (SelectedOptionsExpression is not null) + { + FieldIdentifier = FieldIdentifier.Create(SelectedOptionsExpression); + } + else if (SelectedOptionsChanged.HasDelegate) { FieldIdentifier = FieldIdentifier.Create(() => SelectedOptions); }