From 3b79218b2f9612d7c6215f77726cf8241a9d45c5 Mon Sep 17 00:00:00 2001 From: ScarletKuro Date: Sun, 25 Jan 2026 01:14:59 +0200 Subject: [PATCH 1/2] Fixes --- .../Base/MudBaseInputExtended.cs | 10 ----- .../Components/ChipField/MudChipField.razor | 12 +++--- .../ChipField/MudChipField.razor.cs | 17 ++++---- .../Components/CodeInput/MudCodeInput.razor | 2 +- .../CodeInput/MudCodeInput.razor.cs | 8 ++-- .../Components/ComboBox/MudComboBox.razor | 2 +- .../Components/ComboBox/MudComboBox.razor.cs | 35 ++++++++++----- .../ComboBox/MudComboBoxItem.razor.cs | 40 +++++++++-------- .../ListExtended/MudListExtended.razor.cs | 19 ++++---- .../Components/Loading/MudLoading.razor | 6 +-- .../Components/Loading/MudLoading.razor.cs | 3 +- .../LoadingButton/MudLoadingButton.razor | 8 ++-- .../LoadingButton/MudLoadingButton.razor.cs | 9 ++-- .../PasswordField/MudPasswordField.razor.cs | 3 +- .../RangeSlider/MudRangeSlider.razor.cs | 16 +++---- .../SelectExtended/MudSelectExtended.razor | 4 +- .../SelectExtended/MudSelectExtended.razor.cs | 43 +++++++++---------- .../MudSelectItemExtended.razor | 2 +- .../MudSelectItemExtended.razor.cs | 11 ++--- .../MudSelectItemGroupExtended.razor | 5 +-- .../MudSelectItemGroupExtended.razor.cs | 3 +- .../SpeedDial/MudSpeedDial.razor.cs | 16 +++---- .../Components/Wheel/MudWheel.razor | 1 - .../Components/Wheel/MudWheel.razor.cs | 19 ++++---- .../MultiSelectWithInitialValues.razor | 2 +- .../Components/ChipFieldTests.cs | 4 +- 26 files changed, 144 insertions(+), 156 deletions(-) diff --git a/src/CodeBeam.MudBlazor.Extensions/Base/MudBaseInputExtended.cs b/src/CodeBeam.MudBlazor.Extensions/Base/MudBaseInputExtended.cs index b5ac4cf2..2a75872d 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Base/MudBaseInputExtended.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Base/MudBaseInputExtended.cs @@ -18,12 +18,6 @@ public abstract class MudBaseInputExtended : MudBaseInput /// protected MudBaseInputExtended() { - Converter = new DefaultConverter - { - Culture = GetCulture, - Format = GetFormat - }; - //using var registerScope = CreateRegisterScope(); //_textState = registerScope.RegisterParameter(nameof(Text)) // .WithParameter(() => Text) @@ -41,8 +35,6 @@ protected MudBaseInputExtended() // .WithChangeHandler(UpdateInputIdStateAsync); } - - /// /// Fires on input. /// @@ -171,7 +163,5 @@ public async Task OnBeforeInputFromJs(BeforeInputJsDto dto) /// An object containing event data for the input operation. /// A task that represents the asynchronous operation. The default implementation returns a completed task. protected virtual Task OnBeforeInputAsync(BeforeInputEventArgs args) => Task.CompletedTask; - - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor index f15417c2..28ec6118 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor @@ -12,7 +12,7 @@ OnClearButtonClick="@(async() => await OnClearButtonClick.InvokeAsync())" OnDebounceIntervalElapsed="@(async() => await OnDebounceIntervalElapsed.InvokeAsync())" OnInternalInputChanged="@(async() => await OnInternalInputChanged.InvokeAsync())" - ShrinkLabel="@(Values?.Any() ?? false)" + ShrinkLabel="@(_valuesState.Value?.Any() ?? false)" Clearable="@Clearable" AutoFocus="@AutoFocus" Class="@Class" @@ -43,19 +43,19 @@ Variant="@Variant" @bind-Value="@_internalValue" TextChanged="@(async() => await TextChanged.InvokeAsync())" - ShowVisualiser="@(Values?.Any() ?? false)"> + ShowVisualiser="@(_valuesState.Value?.Any() ?? false)"> - @for (int i = 0; i < (MaxChips == 0 ? Values?.Count ?? 0 : (MaxChips < (Values?.Count ?? 0) ? MaxChips : Values?.Count ?? 0)); i++) + @for (int i = 0; i < (MaxChips == 0 ? _valuesState.Value?.Count ?? 0 : (MaxChips < (_valuesState.Value?.Count ?? 0) ? MaxChips : _valuesState.Value?.Count ?? 0)); i++) { int a = i; - + } - @if (Values != null && MaxChips != 0 && MaxChips < Values.Count) + @if (_valuesState.Value != null && MaxChips != 0 && MaxChips < _valuesState.Value.Count) { - + } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs index 9ecf1755..a6442cd9 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ChipField/MudChipField.razor.cs @@ -48,7 +48,7 @@ public MudChipField() /// /// /The list of values. /// - [Parameter] + [Parameter, ParameterState] public List? Values { get; set; } /// @@ -134,7 +134,7 @@ public MudChipField() /// /// /// - protected internal async Task HandleKeyDown(KeyboardEventArgs args) + protected internal Task HandleKeyDown(KeyboardEventArgs args) { //var result = args.Key; //if (result.Equals(Delimiter, StringComparison.InvariantCultureIgnoreCase) && _internalValue != null) @@ -158,7 +158,7 @@ protected internal async Task HandleKeyDown(KeyboardEventArgs args) //} //await Task.Delay(10); //await SetValueAsync(_internalValue); - await OnKeyDown.InvokeAsync(args); + return OnKeyDown.InvokeAsync(args); } /// @@ -166,9 +166,9 @@ protected internal async Task HandleKeyDown(KeyboardEventArgs args) /// /// /// - protected async Task HandleKeyUp(KeyboardEventArgs args) + protected Task HandleKeyUp(KeyboardEventArgs args) { - await OnKeyUp.InvokeAsync(args); + return OnKeyUp.InvokeAsync(args); } /// @@ -186,7 +186,7 @@ protected internal async Task HandleBeforeInput(BeforeInputEventArgs args) if (args.IsInsert && args.Data == Delimiter && _internalValue is not null) { args.PreventDefault = true; - var currentText = base.ConvertSet(_internalValue); + var currentText = ConvertSet(_internalValue); if (!string.IsNullOrEmpty(currentText)) { @@ -200,7 +200,7 @@ protected internal async Task HandleBeforeInput(BeforeInputEventArgs args) return; } - if (args.IsDeleteBackward && string.IsNullOrEmpty(base.ConvertSet(_internalValue)) && _valuesState.Value is { Count: > 0 } && BackspaceChipRemoval) + if (args.IsDeleteBackward && string.IsNullOrEmpty(ConvertSet(_internalValue)) && _valuesState.Value is { Count: > 0 } && BackspaceChipRemoval) { args.PreventDefault = true; @@ -247,7 +247,7 @@ protected async Task SetChips() { await _valuesState.SetValueAsync(new List()); } - _valuesState.Value.Add(base.ConvertSet(_internalValue) ?? ""); + _valuesState.Value.Add(ConvertSet(_internalValue) ?? ""); await ValuesChanged.InvokeAsync(_valuesState.Value); if (RuntimeLocation.IsServerSide) { @@ -290,6 +290,5 @@ public async Task ClearTextField() { await _textFieldExtendedReference.Clear(); } - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/CodeInput/MudCodeInput.razor b/src/CodeBeam.MudBlazor.Extensions/Components/CodeInput/MudCodeInput.razor index 7ebb19b1..c932279e 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/CodeInput/MudCodeInput.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/CodeInput/MudCodeInput.razor @@ -5,7 +5,7 @@
- @for (int i = 0; i < Count; i++) + @for (int i = 0; i < _count.Value; i++) { int a = i; /// The value of the input. ///
- [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.FormComponent.Behavior)] public T? Value { get; set; } @@ -114,7 +114,7 @@ private async Task OnCountChanged() /// /// The number of text fields. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.FormComponent.Behavior)] public int Count { get; set; } @@ -218,7 +218,7 @@ protected async Task CheckFocus(int count) _skipRefocus = false; return; } - string str = base.ConvertSet(_theValue.Value) ?? string.Empty; + string str = ConvertSet(_theValue.Value) ?? string.Empty; await _elementReferences[str.Length].FocusAsync(); } @@ -298,7 +298,7 @@ public async Task SetValue() /// public async Task SetValueFromOutside(T? value) { - string? val = base.ConvertSet(value); + string? val = ConvertSet(value); if (_count.Value < val?.Length) { val = val.Substring(0, _count.Value); diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor b/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor index 8d1c436a..0825d44e 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor @@ -55,7 +55,7 @@ { foreach (var item in CollectionsMarshal.AsSpan(collection)) { - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs index a3cdaaeb..e8dfcd5a 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs @@ -34,7 +34,7 @@ public MudComboBox() /// protected internal void SetSearchString(T value) { - _searchString = base.ConvertSet(value); + _searchString = ConvertSet(value); } internal string? _searchString { get; set; } @@ -537,7 +537,7 @@ protected async Task SyncMultiselectionValues(bool singleToMultiselection) } else { - if (ReadValue is string && string.IsNullOrWhiteSpace(base.ConvertSet(ReadValue))) + if (ReadValue is string && string.IsNullOrWhiteSpace(ConvertSet(ReadValue))) { SelectedValues = new HashSet(); } @@ -552,7 +552,7 @@ protected async Task SyncMultiselectionValues(bool singleToMultiselection) else { await SetValueAndUpdateTextAsync(SelectedValues.LastOrDefault(), false); - _searchString = base.ConvertSet(SelectedValues.LastOrDefault()); + _searchString = ConvertSet(SelectedValues.LastOrDefault()); } } @@ -655,13 +655,13 @@ protected Task UpdateDataVisualiserTextAsync() { if (!Strict && !Items.Select(x => x.Value).Contains(val)) { - textList.Add(ToStringFunc != null ? ToStringFunc(val) : base.ConvertSet(val)); + textList.Add(ConvertSet(val)); continue; } var item = Items.FirstOrDefault(x => x != null && (x.Value == null ? val == null : Comparer != null ? Comparer.Equals(x.Value, val) : x.Value.Equals(val))); if (item != null) { - textList.Add(!string.IsNullOrWhiteSpace(item.Text) ? item.Text : base.ConvertSet(item.Value)); + textList.Add(!string.IsNullOrWhiteSpace(item.Text) ? item.Text : ConvertSet(item.Value)); } } } @@ -691,8 +691,8 @@ protected Task UpdateDataVisualiserTextAsync() { var item = Items?.FirstOrDefault(x => ReadValue == null ? x.Value == null : Comparer != null ? Comparer.Equals(ReadValue, x.Value) : ReadValue.Equals(x.Value)); _dataVisualiserText = item is null - ? base.ConvertSet(ReadValue) - : (!string.IsNullOrWhiteSpace(item.Text) ? item.Text : base.ConvertSet(item.Value)); + ? ConvertSet(ReadValue) + : (!string.IsNullOrWhiteSpace(item.Text) ? item.Text : ConvertSet(item.Value)); return Task.CompletedTask; } @@ -711,7 +711,7 @@ protected async Task UpdateComboBoxValueAsync(T? value, bool updateText = true, await SetValueAndUpdateTextAsync(value, updateText, force); if (updateSearchString) { - _searchString = base.ConvertSet(ReadValue); + _searchString = ConvertSet(ReadValue); await _inputReference.SetText(_searchString); } } @@ -809,7 +809,7 @@ protected override async Task OnParametersSetAsync() await ForceUpdateItems(); if (MultiSelection == false) { - _searchString = base.ConvertSet(ReadValue); + _searchString = ConvertSet(ReadValue); if (_inputReference != null) { await _inputReference?.SetText(_searchString); @@ -1052,7 +1052,7 @@ protected internal async Task HandleOnBlur(FocusEventArgs obj) if (Strict) { // Check if the user-provided search string is an exact (case-insensitive) match against an item in the collection. - var item = Items.FirstOrDefault(x => base.ConvertSet(x.Value)?.Equals(_searchString, StringComparison.OrdinalIgnoreCase) == true); + var item = Items.FirstOrDefault(x => ConvertSet(x.Value)?.Equals(_searchString, StringComparison.OrdinalIgnoreCase) == true); if (item is not null) await ToggleOption(item, true); @@ -1550,7 +1550,7 @@ public async Task ActivateFirstItem(string? firstLetter = null) // Get a collection of items that start with "firstLetter". - var items = Items.Where(x => base.ConvertSet(x.Value)?.StartsWith(firstLetter, StringComparison.OrdinalIgnoreCase) == true).ToList(); + var items = Items.Where(x => ConvertSet(x.Value)?.StartsWith(firstLetter, StringComparison.OrdinalIgnoreCase) == true).ToList(); if (!items.Any()) { if (_lastActivatedItem is not null) @@ -1701,5 +1701,18 @@ protected bool HasEligibleItems() /// /// protected internal Color EffectiveCheckBoxUnCheckedColor => CheckBoxUnCheckedColor ?? Color; + + /// + protected override string? ConvertSet(T? input) => ConverterSetCore(input); + + internal string? ConverterSetCore(T? input) + { + if (ToStringFunc is null) + { + return base.ConvertSet(input); + } + + return ToStringFunc(input); + } } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs index ee0d6f82..c1c3af5c 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs @@ -1,7 +1,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -using MudBlazor.Extensions; using MudBlazor.Utilities; +using MudBlazor.Extensions; namespace MudExtensions { @@ -43,7 +43,7 @@ public partial class MudComboBoxItem : MudComponentBase, IDisposable /// The parent select component /// [CascadingParameter] - MudComboBox MudComboBox { get; set; } = null!; + private MudComboBox? MudComboBox { get; set; } /// /// Prevents the user from interacting with this item. @@ -150,17 +150,17 @@ protected string? DisplayString { get { - var converter = MudComboBox?.Converter; - if (MudComboBox?.ItemPresenter == ValuePresenter.None) - { - if (converter == null) - return Value?.ToString(); - return converter.Convert(Value); - } - - if (converter == null) - return $"{(string.IsNullOrWhiteSpace(Text) ? Value : Text)}"; - return !string.IsNullOrWhiteSpace(Text) ? Text : converter.Convert(Value); + var hasText = !string.IsNullOrWhiteSpace(Text); + + if (MudComboBox == null) + return hasText ? Text : Value?.ToString(); + + if (MudComboBox.ItemPresenter == ValuePresenter.None) + return MudComboBox.ConverterSetCore(Value); + + return hasText + ? Text + : MudComboBox.ConverterSetCore(Value); } } @@ -259,7 +259,7 @@ protected bool IsEligible() } else { - if (MudComboBox?.Converter?.Convert(Value)?.Contains(MudComboBox._searchString ?? string.Empty, StringComparison.OrdinalIgnoreCase) == true) + if (MudComboBox?.ConverterSetCore(Value)?.Contains(MudComboBox._searchString ?? string.Empty, StringComparison.OrdinalIgnoreCase) == true) return true; } @@ -277,7 +277,7 @@ protected void SyncSelected() if (MudComboBox.MultiSelection && MudComboBox?.SelectedValues?.Contains(Value) == true) Selected = true; - else if (MudComboBox?.MultiSelection == false && ((MudComboBox.Value is null && Value is null) || MudComboBox.Value?.Equals(Value) == true)) + else if (MudComboBox?.MultiSelection == false && ((MudComboBox.GetState(x => x.Value) is null && Value is null) || MudComboBox.GetState(x => x.Value)?.Equals(Value) == true)) Selected = true; else Selected = false; @@ -289,9 +289,13 @@ protected void SyncSelected() /// protected async Task HandleOnClick() { - await MudComboBox.ToggleOption(this, !Selected); - await InvokeAsync(StateHasChanged); - await MudComboBox.FocusAsync(); + if (MudComboBox is not null) + { + await MudComboBox.ToggleOption(this, !Selected); + await InvokeAsync(StateHasChanged); + await MudComboBox.FocusAsync(); + } + await OnClick.InvokeAsync(); } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs index 364d5d2d..5bab7144 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs @@ -32,20 +32,21 @@ public partial class MudListExtended : MudComponentBase, IDisposable /// /// protected string? Classname => - new CssBuilder("mud-list-extended") - .AddClass("mud-list-padding-extended", Padding) - .AddClass(Class) - .Build(); + new CssBuilder("mud-list-extended") + .AddClass("mud-list-padding-extended", Padding) + .AddClass(Class) + .Build(); /// /// /// protected string? Stylename => - new StyleBuilder() - .AddStyle("max-height", $"{MaxItems * (!Dense ? 48 : 36) + (Padding == false ? 0 : 16)}px", MaxItems != null) - .AddStyle("overflow-y", "auto", MaxItems != null) - .AddStyle(Style) - .Build(); + new StyleBuilder() + .AddStyle("max-height", $"{MaxItems * (!Dense ? 48 : 36) + (Padding == false ? 0 : 16)}px", + MaxItems != null) + .AddStyle("overflow-y", "auto", MaxItems != null) + .AddStyle(Style) + .Build(); /// /// diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor b/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor index 55841237..883ca426 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor @@ -1,7 +1,7 @@ @namespace MudExtensions @inherits MudComponentBase -@if (_loading.Value == true) +@if (_loading.Value) { if (LoaderType == LoaderType.Circular) { @@ -11,7 +11,7 @@ } else { - +
@Text @@ -31,7 +31,7 @@ @Text - +
diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor.cs index 22390ecd..a0990666 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/Loading/MudLoading.razor.cs @@ -34,7 +34,7 @@ public MudLoading() /// /// Two way binded loading state. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.FormComponent.Behavior)] public bool Loading { get; set; } @@ -120,6 +120,5 @@ public MudLoading() [Parameter] [Category(CategoryTypes.FormComponent.Appearance)] public RenderFragment? ChildContent { get; set; } - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/LoadingButton/MudLoadingButton.razor b/src/CodeBeam.MudBlazor.Extensions/Components/LoadingButton/MudLoadingButton.razor index 9c83a745..59c466d0 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/LoadingButton/MudLoadingButton.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/LoadingButton/MudLoadingButton.razor @@ -3,7 +3,7 @@ @if (ButtonVariant == ButtonVariant.Button) { - @@ -63,9 +63,9 @@ else if (ButtonVariant == ButtonVariant.IconButton) } else if (ButtonVariant == ButtonVariant.Fab) { - @if (_loading.Value == false) + @if (!_loading.Value) { - public partial class MudLoadingButton : MudBaseButton { - /// /// MudLoadingButton constructor. /// @@ -25,9 +24,9 @@ public MudLoadingButton() private readonly ParameterState _loading; /// - /// Two way binded loading state. + /// Two-way bind loading state. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.FormComponent.Behavior)] public bool Loading { get; set; } @@ -150,7 +149,7 @@ public MudLoadingButton() public string? Label { get; set; } /// - /// If not null, LoadingButton goes for loading state for determined miliseconds. + /// If not null, LoadingButton goes for loading state for determined milliseconds. /// [Parameter] [Category(CategoryTypes.FormComponent.Appearance)] @@ -163,7 +162,6 @@ public MudLoadingButton() /// protected async Task ButtonClick(MouseEventArgs args) { - if (AutoDelay != null) { Task task = Task.Delay(AutoDelay.Value); @@ -177,6 +175,5 @@ protected async Task ButtonClick(MouseEventArgs args) await OnClickHandler(args); } } - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/PasswordField/MudPasswordField.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/PasswordField/MudPasswordField.razor.cs index 09b02f50..f90bd4ca 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/PasswordField/MudPasswordField.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/PasswordField/MudPasswordField.razor.cs @@ -166,7 +166,7 @@ private async Task OnMaskedValueChanged(string s) /// /// If true, masks text with password mode. /// - [Parameter] + [Parameter, ParameterState] public bool PasswordMode { get; set; } = true; /// @@ -184,6 +184,5 @@ protected async Task AdornmentClick() await _passwordMode.SetValueAsync(!_passwordMode.Value); await OnAdornmentClick.InvokeAsync(); } - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/RangeSlider/MudRangeSlider.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/RangeSlider/MudRangeSlider.razor.cs index 986936ef..fdb396b3 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/RangeSlider/MudRangeSlider.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/RangeSlider/MudRangeSlider.razor.cs @@ -13,7 +13,6 @@ namespace MudExtensions /// public partial class MudRangeSlider : MudComponentBase where T : struct, INumber { - private readonly ParameterState _value; private readonly ParameterState _upperValue; private readonly ParameterState _slideableMin; @@ -169,14 +168,14 @@ private async Task OnSlideableLowerMaxChanged() /// /// The minimum value can slider thumb has. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.Slider.Validation)] public T? SlideableMin { get; set; } /// /// The minimum value the upper slider thumb can have. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.Slider.Validation)] public T? SlideableUpperMin { get; set; } @@ -190,14 +189,14 @@ private async Task OnSlideableLowerMaxChanged() /// /// The maximum value can slider thumb has. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.Slider.Validation)] public T? SlideableMax { get; set; } /// /// The maximum value the lower slider thumb can have. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.Slider.Validation)] public T? SlideableLowerMax { get; set; } @@ -249,7 +248,7 @@ private async Task OnSlideableLowerMaxChanged() public RenderFragment? ChildContent { get; set; } /// - /// + /// Converter for this component. /// [Parameter] [Category(CategoryTypes.Slider.Behavior)] @@ -268,14 +267,14 @@ private async Task OnSlideableLowerMaxChanged() /// /// Value of the component. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.Slider.Data)] public T Value { get; set; } = T.Zero; /// /// If range set, holds the higher value. /// - [Parameter] + [Parameter, ParameterState] [Category(CategoryTypes.Slider.Data)] public T UpperValue { get; set; } = T.CreateTruncating(50); @@ -451,6 +450,5 @@ private async Task SetUpperValueTextAsync(string? text) await _upperValue.SetValueAsync(result); } } - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor index 70e747ad..dca0aa16 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor @@ -75,14 +75,14 @@ { foreach (var item in ItemCollection.Where(x => SelectedValues?.Contains(x) == true)) { - + } } else { foreach (var item in Items?.Where(x => SelectedValues?.Contains(x.Value) == true) ?? new List>()) { - + } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs index f9b6041a..73b225e5 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs @@ -518,29 +518,12 @@ public IEqualityComparer? Comparer } } - private Func? _toStringFunc = x => x?.ToString(); /// /// Defines how values are displayed in the drop-down list /// [Parameter] [Category(CategoryTypes.FormComponent.ListBehavior)] - public Func? ToStringFunc - { - get => _toStringFunc; - set - { - if (_toStringFunc == value) - return; - _toStringFunc = value; - Converter = Conversions.From( - x => _toStringFunc?.Invoke(x) ?? x?.ToString() ?? string.Empty, - _ => throw new NotSupportedException("String -> T conversion is not supported.")); - //Converter = new DefaultConverter - //{ - // SetFunc = _toStringFunc ?? (x => x?.ToString()), - //}; - } - } + public Func? ToStringFunc { get; set; } /// /// If true, a null item will be added to the list (Only for ItemCollection). @@ -721,7 +704,7 @@ protected override Task UpdateTextPropertyAsync(bool updateValue) var collectionValue = ItemCollection.FirstOrDefault(x => x != null && (Comparer != null ? Comparer.Equals(x, val) : x.Equals(val))); if (collectionValue != null) { - textList.Add(base.ConvertSet(collectionValue)); + textList.Add(ConvertSet(collectionValue)); } } } @@ -731,13 +714,13 @@ protected override Task UpdateTextPropertyAsync(bool updateValue) { if (!Strict && !Items.Select(x => x.Value).Contains(val)) { - textList.Add(ToStringFunc != null ? ToStringFunc(val) : base.ConvertSet(val)); + textList.Add(ToStringFunc != null ? ToStringFunc(val) : ConvertSet(val)); continue; } var item = Items.FirstOrDefault(x => x != null && (x.Value == null ? val == null : Comparer != null ? Comparer.Equals(x.Value, val) : x.Value.Equals(val))); if (item != null) { - textList.Add(!string.IsNullOrEmpty(item.Text) ? item.Text : base.ConvertSet(item.Value)); + textList.Add(!string.IsNullOrEmpty(item.Text) ? item.Text : ConvertSet(item.Value)); } } } @@ -763,9 +746,9 @@ protected override Task UpdateTextPropertyAsync(bool updateValue) var item = Items?.FirstOrDefault(x => ReadValue == null ? x.Value == null : Comparer != null ? Comparer.Equals(ReadValue, x.Value) : ReadValue.Equals(x.Value)); if (item == null) { - return SetTextAndUpdateValueAsync(base.ConvertSet(ReadValue), false); + return SetTextAndUpdateValueAsync(ConvertSet(ReadValue), false); } - return SetTextAndUpdateValueAsync((!string.IsNullOrEmpty(item.Text) ? item.Text : base.ConvertSet(item.Value)), updateValue: updateValue); + return SetTextAndUpdateValueAsync((!string.IsNullOrEmpty(item.Text) ? item.Text : ConvertSet(item.Value)), updateValue: updateValue); } } @@ -1352,5 +1335,19 @@ public bool GetOpenState() { return _isOpen; } + + /// + protected override string? ConvertSet(T? input) => ConverterSetCore(input); + + internal string? ConverterSetCore(T? input) + { + if (ToStringFunc is null) + { + return base.ConvertSet(input); + } + + var n = ToStringFunc(input); + return ToStringFunc(input); + } } } \ No newline at end of file diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor index 31b1ee79..5470bc69 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor @@ -2,7 +2,7 @@ @typeparam T @inherits MudComponentBase -@if (HideContent == false) +@if (!HideContent) { @if (ChildContent != null && MudSelectExtended?.ItemCollection == null) diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs index 97803105..5ff6c205 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs @@ -10,7 +10,7 @@ namespace MudExtensions /// public partial class MudSelectItemExtended : MudComponentBase, IDisposable { - private String GetCssClasses() => new CssBuilder() + private string GetCssClasses() => new CssBuilder() .AddClass(Class) .Build(); @@ -150,10 +150,12 @@ protected string? DisplayString { get { - var converter = MudSelectExtended?.GetState(x => x.Converter); - if (converter == null) + if (MudSelectExtended == null) + { return $"{(string.IsNullOrEmpty(Text) ? Value : Text)}"; - return !string.IsNullOrEmpty(Text) ? Text : converter.Convert(Value); + } + + return !string.IsNullOrEmpty(Text) ? Text : MudSelectExtended.ConverterSetCore(Value); } } @@ -189,7 +191,6 @@ protected bool GetDisabledStatus() return Disabled; } - /// /// /// diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor index ee13f74c..5b91949b 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor @@ -2,10 +2,9 @@ @typeparam T @inherits MudComponentBase -@if (HideContent == false) +@if (!HideContent) { - - if (Nested == true) + if (Nested) { diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs index c3d974f4..c4b2ced5 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs @@ -59,7 +59,7 @@ public partial class MudSelectItemGroupExtended : MudComponentBase /// /// Select items with HideContent==true are only there to register their RenderFragment with the select but - /// wont render and have no other purpose! + /// Won't render and have no other purpose! /// [CascadingParameter(Name = "HideContent")] internal bool HideContent { get; set; } @@ -86,6 +86,5 @@ protected override async Task OnAfterRenderAsync(bool firstRender) MudListExtended?.UpdateSelectedStyles(false); } } - } } diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SpeedDial/MudSpeedDial.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/SpeedDial/MudSpeedDial.razor.cs index 15009095..c398873d 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SpeedDial/MudSpeedDial.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SpeedDial/MudSpeedDial.razor.cs @@ -10,21 +10,22 @@ namespace MudExtensions /// public partial class MudSpeedDial : MudComponentBase { + private bool _row; + private Origin _anchorOrigin = Origin.TopCenter; + private Origin _transformOrigin = Origin.BottomCenter; + private readonly Guid _animationGuid = Guid.NewGuid(); + /// /// MudLoading constructor. /// public MudSpeedDial() { using var registerScope = CreateRegisterScope(); - _origin = registerScope.RegisterParameter(nameof(Origin)) + registerScope.RegisterParameter(nameof(Origin)) .WithParameter(() => Origin) .WithChangeHandler(UpdateOrigin); } - private readonly ParameterState _origin; - - Guid _animationGuid = Guid.NewGuid(); - /// /// /// @@ -127,7 +128,7 @@ public MudSpeedDial() /// /// /// - [Parameter] + [Parameter, ParameterState(ParameterUsage = ParameterUsageOptions.None)] public Origin Origin { get; set; } = Origin.BottomRight; /// @@ -261,9 +262,6 @@ protected void HandlePopoverClick() } } - bool _row = false; - Origin _anchorOrigin = Origin.TopCenter; - Origin _transformOrigin = Origin.BottomCenter; /// /// /// diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor b/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor index 1bd0873d..d41bfe8a 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor @@ -1,7 +1,6 @@ @namespace MudExtensions @typeparam T @inherits MudBaseInput -@using MudExtensions.Utilities
@if (!string.IsNullOrEmpty(Label)) diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs index c0870330..59eeb873 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; using MudBlazor; -using MudBlazor.Extensions; using MudBlazor.Utilities; namespace MudExtensions @@ -12,10 +11,15 @@ namespace MudExtensions /// public partial class MudWheel : MudBaseInput { + private int _animateValue = 52; + private MudAnimate _animate = new(); + private readonly Guid _animateGuid = Guid.NewGuid(); + /// /// /// - [Inject] public IScrollManager ScrollManager { get; set; } = null!; + [Inject] + public IScrollManager ScrollManager { get; set; } = null!; /// /// @@ -67,15 +71,11 @@ public partial class MudWheel : MudBaseInput .AddClass("wheel-item-empty-dense", Dense) .Build(); - MudAnimate _animate = new(); - Guid _animateGuid = Guid.NewGuid(); - int _animateValue = 52; - /// /// /// [Parameter] - public List ItemCollection { get; set; } = new(); + public List? ItemCollection { get; set; } = new(); /// /// Determines how many items will show before and after the middle one. @@ -113,7 +113,6 @@ public partial class MudWheel : MudBaseInput [Parameter] public Color Color { get; set; } - private Func? _toStringFunc = x => x?.ToString(); /// /// Defines how values are displayed in the drop-down list /// @@ -258,7 +257,7 @@ public async Task ChangeWheel(int changeCount) } await _animate.Refresh(); - T val = ItemCollection[index + changeCount]; + T? val = ItemCollection is not null ? ItemCollection[index + changeCount] : default; await SetValueAsync(val); } @@ -282,7 +281,5 @@ public async Task RefreshAnimate() /// /// protected int GetAnimateValue() => Dense ? 24 : 42; - - } } diff --git a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor index c33e55f0..32d4d2ba 100644 --- a/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor +++ b/tests/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithInitialValues.razor @@ -28,7 +28,7 @@ await base.OnInitializedAsync(); } - private string ToString(TestItem x) + private string ToString(TestItem? x) => x is null ? string.Empty : $"{x.A}"; private class TestItem diff --git a/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ChipFieldTests.cs b/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ChipFieldTests.cs index 4a960388..03609994 100644 --- a/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ChipFieldTests.cs +++ b/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ChipFieldTests.cs @@ -1,9 +1,7 @@ using Bunit; using AwesomeAssertions; using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; using MudBlazor.Extensions; -using MudExtensions.Docs.Examples; namespace MudExtensions.UnitTests.Components { @@ -20,7 +18,7 @@ public async Task ChipFieldBasicTest() var field = comp.FindComponent>(); field.Find("input").Input(new ChangeEventArgs() { Value = "sdfg" }); await comp.InvokeAsync(() => comp.Instance.HandleBeforeInput(new BeforeInputEventArgs() { Data = " ", InputType = "insert" })); - comp.Instance.Values.Should().BeEquivalentTo(new List { "asdf", "asd", "sdfg" }); + comp.Instance.GetState(x => x.Values).Should().BeEquivalentTo(new List { "asdf", "asd", "sdfg" }); comp.Instance.GetState(x => x.Value).Should().BeEquivalentTo(null); } } From 5b22e90fa4d9cd6de031b6db1b55ebc3cad91052 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Sun, 25 Jan 2026 22:14:33 +0300 Subject: [PATCH 2/2] Fix Firefox WASM crash on input components & Some More Sync Changes --- .../wwwroot/CodeBeam.MudBlazor.Extensions.xml | 47 +++++++++++++++---- .../InputExtended/MudInputExtended.razor | 3 -- .../SelectExtended/MudSelectExtended.razor.cs | 4 +- .../MudSelectItemExtended.razor.cs | 2 +- .../MudTextFieldExtended.razor | 4 +- .../MudTextFieldExtended.razor.cs | 14 ++---- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml b/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml index 35a1550f..600b4649 100644 --- a/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml +++ b/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml @@ -361,6 +361,12 @@ + + + + + + @@ -673,6 +679,17 @@ If set to true and the MultiSelection option is set to true, a "select all" checkbox is added at the top of the list of items. + + + If true prevent background interaction when open. Default is true. + + + + + + + + Sets position of the Select All checkbox @@ -1120,6 +1137,9 @@ + + + @@ -2937,7 +2957,7 @@ - Two way binded loading state. + Two-way bind loading state. @@ -3027,7 +3047,7 @@ - If not null, LoadingButton goes for loading state for determined miliseconds. + If not null, LoadingButton goes for loading state for determined milliseconds. @@ -3552,7 +3572,7 @@ - + Converter for this component. @@ -3752,6 +3772,17 @@ If false multiline text show. Default is false. + + + If true prevent background interaction when open. Default is true. + + + + + + + + User class names for the popover, separated by space @@ -4224,6 +4255,9 @@ + + + Represents an option of a select or multi-select. To be used inside MudSelect. @@ -4344,7 +4378,7 @@ Select items with HideContent==true are only there to register their RenderFragment with the select but - wont render and have no other purpose! + Won't render and have no other purpose! @@ -5461,11 +5495,6 @@ - - - - - diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor b/src/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor index a28cc04f..6f506589 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor @@ -30,7 +30,6 @@ @onblur="@OnBlurredAsync" @onkeydown="@InvokeKeyDownAsync" @onkeyup="@InvokeKeyUpAsync" - @onbeforeinput="@InvokeBeforeInputAsync" @onpaste="@OnPaste" maxlength="@MaxLength" @onkeydown:preventDefault="@KeyDownPreventDefault" @@ -75,7 +74,6 @@ pattern="@Pattern" @onkeydown="@InvokeKeyDownAsync" @onkeyup="@InvokeKeyUpAsync" - @onbeforeinput="@InvokeBeforeInputAsync" maxlength="@MaxLength" @onkeydown:preventDefault="KeyDownPreventDefault" @onkeyup:preventDefault="@KeyUpPreventDefault" @@ -105,7 +103,6 @@ pattern="@Pattern" @onkeydown="@InvokeKeyDownAsync" @onkeyup="@InvokeKeyUpAsync" - @onbeforeinput="@InvokeBeforeInputAsync" maxlength="@MaxLength" @onkeydown:preventDefault="KeyDownPreventDefault" @onkeyup:preventDefault="@KeyUpPreventDefault" diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs index 73b225e5..d177b2ec 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor.cs @@ -85,8 +85,8 @@ public MudSelectExtended() .AddClass("mud-select-extended-nowrap mud-chip-scroll-container", NoWrap) .Build(); - private string _elementId = "select_" + Guid.NewGuid().ToString().Substring(0, 8); - private string _popoverId = "selectpopover_" + Guid.NewGuid().ToString().Substring(0, 8); + private string _elementId = Identifier.Create("selectext"); + private string _popoverId = Identifier.Create("selectpopover_"); /// /// User class names for the input, separated by space diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs index 5ff6c205..f42fc13c 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs @@ -20,7 +20,7 @@ public partial class MudSelectItemExtended : MudComponentBase, IDisposable /// /// public MudListItemExtended ListItem { get; set; } = new(); - internal string ItemId { get; } = "selectItem_"+Guid.NewGuid().ToString().Substring(0,8); + internal string ItemId { get; } = Identifier.Create("selectItem_"); private IMudShadowSelectExtended? _shadowParent; /// diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor b/src/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor index 296f8a12..0b4c8c9e 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor @@ -2,7 +2,7 @@ @typeparam T @inherits MudDebouncedInputExtended - + - + @if (_mask == null) { : MudDebouncedInputExtended /// /// protected string? Classname => - new CssBuilder("mud-input-input-control") - .AddClass("mud-no-start-adornment", AdornmentStart == null) - .AddClass(Class) - .Build(); - - /// - /// - /// - [CascadingParameter] - public bool SubscribeToParentForm2 { get; set; } + new CssBuilder("mud-input-input-control") + .AddClass("mud-no-start-adornment", AdornmentStart == null) + .AddClass(Class) + .Build(); /// ///