From 50d02c514e0962c49571f9dc31fe6d6ed1ca90ae Mon Sep 17 00:00:00 2001 From: Bernhard Straub Date: Fri, 12 Jan 2024 20:21:07 +0100 Subject: [PATCH 1/3] VSCode Fixe settings --- .vscode/launch.json | 2 +- .vscode/tasks.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 2a558a7..0d68810 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "name": "Launch and Debug Standalone Blazor WebAssembly App", "type": "blazorwasm", "request": "launch", - "cwd": "${workspaceFolder}/RxBlazorLightSample" + "cwd": "${workspaceFolder}/RxMudBlazorLightSample" } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 61fff92..d326d96 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -19,7 +19,7 @@ "type": "process", "args": [ "publish", - "${workspaceFolder}/RxBlazorLightSample/RxBlazorLightSample.csproj", + "${workspaceFolder}/RxMudBlazorLightSample/RxMudBlazorLightSample.csproj", "/property:GenerateFullPaths=true", "/consoleloggerparameters:NoSummary" ], @@ -33,7 +33,7 @@ "watch", "run", "--project", - "${workspaceFolder}/RxBlazorLightSample/RxBlazorLightSample.csproj" + "${workspaceFolder}/RxMudBlazorLightSample/RxMudBlazorLightSample.csproj" ], "problemMatcher": "$msCompile" } From f9f0c112a9ace6c9d7450d5a6b91cc4c6832012b Mon Sep 17 00:00:00 2001 From: Bernhard Straub Date: Fri, 19 Jan 2024 12:52:40 +0100 Subject: [PATCH 2/3] RX Service Revise usage of singleton and scoped services + better naming of components --- RxBlazorLight.sln | 11 + .../Component/RxBLServiceContext.cs | 22 ++ .../Component/RxBLServiceContext.razor | 34 --- .../Component/RxBLServiceScope.razor | 8 + .../Component/RxBLServiceScope.razor.cs | 32 +++ RxBlazorLightCore/Core/Commands.cs | 22 +- RxBlazorLightCore/Core/Input.cs | 249 +++--------------- RxBlazorLightCore/Core/Interfaces.cs | 46 ++-- .../Core/{ServiceBase.cs => Service.cs} | 41 ++- RxBlazorLightCore/Core/ServiceExtensions.cs | 33 ++- RxMudBlazorLight/ButtonBase/ButtonAsyncPRx.cs | 1 - RxMudBlazorLight/ButtonBase/ButtonAsyncRx.cs | 1 - .../Buttons/MudButtonAsyncPRx.razor | 7 +- .../Buttons/MudButtonAsyncRx.razor | 7 +- RxMudBlazorLight/Buttons/MudButtonPRx.razor | 14 +- RxMudBlazorLight/Buttons/MudButtonRx.razor | 14 +- RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor | 2 +- .../Dialogs/DialogAsyncPRx.razor.cs | 2 +- RxMudBlazorLight/Dialogs/DialogAsyncRx.razor | 2 +- .../Dialogs/DialogAsyncRx.razor.cs | 2 +- .../FabButtons/MudFabAsyncPRx.razor | 13 +- .../FabButtons/MudFabAsyncRx.razor | 13 +- RxMudBlazorLight/FabButtons/MudFabPRx.razor | 13 +- RxMudBlazorLight/FabButtons/MudFabRx.razor | 14 +- .../IconButtons/MudIconButtonAsyncPRx.razor | 14 +- .../IconButtons/MudIconButtonAsyncRx.razor | 12 +- .../IconButtons/MudIconButtonPRx.razor | 13 +- .../IconButtons/MudIconButtonRx.razor | 14 +- .../Inputs/MudAutocompleteAsyncRx.razor | 26 -- .../Inputs/MudAutocompleteRx.razor | 8 +- .../Inputs/MudCheckBoxAsyncRx.razor | 29 -- RxMudBlazorLight/Inputs/MudCheckBoxRx.razor | 8 +- .../Inputs/MudNumericFieldAsyncRx.razor | 31 --- .../Inputs/MudNumericFieldRx.razor | 8 +- .../Inputs/MudRatingAsyncRx.razor | 21 -- RxMudBlazorLight/Inputs/MudRatingRx.razor | 14 +- .../Inputs/MudSliderAsyncRx.razor | 22 -- RxMudBlazorLight/Inputs/MudSliderRx.razor | 8 +- .../Inputs/MudSwitchAsyncRx.razor | 29 -- RxMudBlazorLight/Inputs/MudSwitchRx.razor | 8 +- .../Inputs/MudTextFieldAsyncRx.razor | 26 -- RxMudBlazorLight/Inputs/MudTextFieldRx.razor | 13 +- .../Inputs/Radio/MudRadioGroupAsyncBaseRx.cs | 74 ------ .../Inputs/Radio/MudRadioGroupAsyncPRx.razor | 36 --- .../Inputs/Radio/MudRadioGroupAsyncRx.razor | 22 -- .../Inputs/Radio/MudRadioGroupBaseRx.cs | 4 +- .../Inputs/Radio/MudRadioGroupPRx.razor | 36 --- .../Inputs/Radio/MudRadioGroupRx.razor | 8 +- .../Inputs/Select/MudSelectAsyncBaseRx.cs | 82 ------ .../Inputs/Select/MudSelectAsyncPRx.razor | 36 --- .../Inputs/Select/MudSelectAsyncRx.razor | 22 -- .../Inputs/Select/MudSelectBaseRx.cs | 3 +- .../Inputs/Select/MudSelectPRx.razor | 36 --- .../Inputs/Select/MudSelectRx.razor | 8 +- RxMudBlazorLight/Menus/MudMenuItemPRx.razor | 13 +- RxMudBlazorLight/Menus/MudMenuItemRx.razor | 14 +- RxMudBlazorLight/RxMudBlazorLight.csproj | 2 +- .../MudToggleIconButtonRx.razor | 10 +- RxMudBlazorLight/_Imports.razor | 3 +- RxMudBlazorLightSample/Pages/Index.razor | 4 +- RxMudBlazorLightSample/Program.cs | 6 +- .../Shared/MainLayout.razor | 5 +- RxMudBlazorLightSample/_Imports.razor | 1 - .../Components/ButtonTest.razor | 124 ++++----- .../Components/IconButtons.razor | 15 ++ .../Components/InputTest.razor | 91 +++---- .../Components/TestPlayground.razor | 32 +-- .../Components/TimerComponent.razor | 15 +- .../Service/TestService.Commands.cs | 10 +- .../Service/TestService.Input.cs | 57 +--- .../Service/TestService.cs | 71 +++-- .../Service/TimerService.cs | 55 ++++ .../Service/TimerServices.cs | 40 --- RxMudBlazorLightTestBase/_Imports.razor | 1 - .../Context/TestContextBase.cs | 7 +- .../Extensions/TestExtensions.cs | 72 ++--- .../RxMudBlazorLightTests.csproj | 2 - .../TestPlaygroundComponent.razor | 7 +- RxMudBlazorLightTests/_Imports.razor | 1 - 79 files changed, 605 insertions(+), 1327 deletions(-) create mode 100644 RxBlazorLightCore/Component/RxBLServiceContext.cs delete mode 100644 RxBlazorLightCore/Component/RxBLServiceContext.razor create mode 100644 RxBlazorLightCore/Component/RxBLServiceScope.razor create mode 100644 RxBlazorLightCore/Component/RxBLServiceScope.razor.cs rename RxBlazorLightCore/Core/{ServiceBase.cs => Service.cs} (63%) delete mode 100644 RxMudBlazorLight/Inputs/MudAutocompleteAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/MudCheckBoxAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/MudNumericFieldAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/MudRatingAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/MudSliderAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/MudSwitchAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/MudTextFieldAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncBaseRx.cs delete mode 100644 RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncPRx.razor delete mode 100644 RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/Radio/MudRadioGroupPRx.razor delete mode 100644 RxMudBlazorLight/Inputs/Select/MudSelectAsyncBaseRx.cs delete mode 100644 RxMudBlazorLight/Inputs/Select/MudSelectAsyncPRx.razor delete mode 100644 RxMudBlazorLight/Inputs/Select/MudSelectAsyncRx.razor delete mode 100644 RxMudBlazorLight/Inputs/Select/MudSelectPRx.razor create mode 100644 RxMudBlazorLightTestBase/Components/IconButtons.razor create mode 100644 RxMudBlazorLightTestBase/Service/TimerService.cs delete mode 100644 RxMudBlazorLightTestBase/Service/TimerServices.cs diff --git a/RxBlazorLight.sln b/RxBlazorLight.sln index ce89450..7ff7613 100644 --- a/RxBlazorLight.sln +++ b/RxBlazorLight.sln @@ -18,27 +18,38 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + DebugKeepJS|Any CPU = DebugKeepJS|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {72C03536-9A0D-444D-BD35-346672CAAA1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {72C03536-9A0D-444D-BD35-346672CAAA1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72C03536-9A0D-444D-BD35-346672CAAA1E}.DebugKeepJS|Any CPU.ActiveCfg = Debug|Any CPU + {72C03536-9A0D-444D-BD35-346672CAAA1E}.DebugKeepJS|Any CPU.Build.0 = Debug|Any CPU {72C03536-9A0D-444D-BD35-346672CAAA1E}.Release|Any CPU.ActiveCfg = Release|Any CPU {72C03536-9A0D-444D-BD35-346672CAAA1E}.Release|Any CPU.Build.0 = Release|Any CPU {0441C22D-02FC-4B54-BE53-D3F32EF779CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0441C22D-02FC-4B54-BE53-D3F32EF779CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0441C22D-02FC-4B54-BE53-D3F32EF779CE}.DebugKeepJS|Any CPU.ActiveCfg = Debug|Any CPU + {0441C22D-02FC-4B54-BE53-D3F32EF779CE}.DebugKeepJS|Any CPU.Build.0 = Debug|Any CPU {0441C22D-02FC-4B54-BE53-D3F32EF779CE}.Release|Any CPU.ActiveCfg = Release|Any CPU {0441C22D-02FC-4B54-BE53-D3F32EF779CE}.Release|Any CPU.Build.0 = Release|Any CPU {F15C97D9-B35A-41DC-B32E-751357106EC2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F15C97D9-B35A-41DC-B32E-751357106EC2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F15C97D9-B35A-41DC-B32E-751357106EC2}.DebugKeepJS|Any CPU.ActiveCfg = Debug|Any CPU + {F15C97D9-B35A-41DC-B32E-751357106EC2}.DebugKeepJS|Any CPU.Build.0 = Debug|Any CPU {F15C97D9-B35A-41DC-B32E-751357106EC2}.Release|Any CPU.ActiveCfg = Release|Any CPU {F15C97D9-B35A-41DC-B32E-751357106EC2}.Release|Any CPU.Build.0 = Release|Any CPU {600C1493-DE8C-47A9-99CC-19EE49ECAB6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {600C1493-DE8C-47A9-99CC-19EE49ECAB6F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {600C1493-DE8C-47A9-99CC-19EE49ECAB6F}.DebugKeepJS|Any CPU.ActiveCfg = Debug|Any CPU + {600C1493-DE8C-47A9-99CC-19EE49ECAB6F}.DebugKeepJS|Any CPU.Build.0 = Debug|Any CPU {600C1493-DE8C-47A9-99CC-19EE49ECAB6F}.Release|Any CPU.ActiveCfg = Release|Any CPU {600C1493-DE8C-47A9-99CC-19EE49ECAB6F}.Release|Any CPU.Build.0 = Release|Any CPU {ED0AFCB2-A7DC-48F8-9E99-A66493925FD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {ED0AFCB2-A7DC-48F8-9E99-A66493925FD8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ED0AFCB2-A7DC-48F8-9E99-A66493925FD8}.DebugKeepJS|Any CPU.ActiveCfg = Debug|Any CPU + {ED0AFCB2-A7DC-48F8-9E99-A66493925FD8}.DebugKeepJS|Any CPU.Build.0 = Debug|Any CPU {ED0AFCB2-A7DC-48F8-9E99-A66493925FD8}.Release|Any CPU.ActiveCfg = Release|Any CPU {ED0AFCB2-A7DC-48F8-9E99-A66493925FD8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/RxBlazorLightCore/Component/RxBLServiceContext.cs b/RxBlazorLightCore/Component/RxBLServiceContext.cs new file mode 100644 index 0000000..f94357b --- /dev/null +++ b/RxBlazorLightCore/Component/RxBLServiceContext.cs @@ -0,0 +1,22 @@ +using Microsoft.AspNetCore.Components; + +namespace RxBlazorLightCore; + +public class RxBLServiceContext : ComponentBase +{ + [Inject] + public RxServiceCollector? ServiceCollector { get; init; } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender && ServiceCollector is not null) + { + foreach (var service in ServiceCollector.Services) + { + await service.OnContextReadyAsync(); + } + } + + await base.OnAfterRenderAsync(firstRender); + } +} diff --git a/RxBlazorLightCore/Component/RxBLServiceContext.razor b/RxBlazorLightCore/Component/RxBLServiceContext.razor deleted file mode 100644 index 09e009d..0000000 --- a/RxBlazorLightCore/Component/RxBLServiceContext.razor +++ /dev/null @@ -1,34 +0,0 @@ -@typeparam TService where TService : RxBLServiceBase -@implements IDisposable - - - @ChildContent - - -@code { - [CascadingParameter] - public required TService Service { get; init; } - - [Parameter] - public required RenderFragment ChildContent { get; init; } - - public bool ServiceInitialized => _initialized; - - private bool _initialized = false; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - await Service.OnContextInitialized(); - _initialized = true; - } - } - - public void Dispose() - { - Service.OnContextDisposed(); - } -} diff --git a/RxBlazorLightCore/Component/RxBLServiceScope.razor b/RxBlazorLightCore/Component/RxBLServiceScope.razor new file mode 100644 index 0000000..737dd28 --- /dev/null +++ b/RxBlazorLightCore/Component/RxBLServiceScope.razor @@ -0,0 +1,8 @@ +@namespace RxBlazorLightCore +@typeparam TScope where TScope : IRxBLScope +@typeparam TService where TService : IRxBLService +@implements IDisposable + + + @ChildContent + diff --git a/RxBlazorLightCore/Component/RxBLServiceScope.razor.cs b/RxBlazorLightCore/Component/RxBLServiceScope.razor.cs new file mode 100644 index 0000000..badf63e --- /dev/null +++ b/RxBlazorLightCore/Component/RxBLServiceScope.razor.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Components; +using System.Diagnostics.CodeAnalysis; + +namespace RxBlazorLightCore +{ + public sealed partial class RxBLServiceScope : ComponentBase, IDisposable where TService : IRxBLService + where TScope : IRxBLScope + { + [CascadingParameter] + public required TService Service { get; init; } + + [Parameter] + public required RenderFragment ChildContent { get; init; } + + [NotNull] + private TScope? Scope { get; set; } + + protected override void OnInitialized() + { + ArgumentNullException.ThrowIfNull(Service); + Scope = (TScope)Service.CreateScope(); + Scope.EnterScope(); + ArgumentNullException.ThrowIfNull(Scope); + base.OnInitialized(); + } + + public void Dispose() + { + Scope.LeaveScope(); + } + } +} diff --git a/RxBlazorLightCore/Core/Commands.cs b/RxBlazorLightCore/Core/Commands.cs index 7f2401f..64a66f4 100644 --- a/RxBlazorLightCore/Core/Commands.cs +++ b/RxBlazorLightCore/Core/Commands.cs @@ -77,7 +77,7 @@ public void Execute() LastException = ex; } - Changed(LastException is not null ? CommandState.EXCEPTION : + Changed(LastException is not null ? CommandState.EXCEPTION : executed ? CommandState.EXECUTED : CommandState.NOT_EXECUTED); } } @@ -145,7 +145,7 @@ public virtual void Execute() } } - public abstract class CommandService : Command, IDisposable where S : IRxService + public abstract class CommandService : Command, IDisposable where S : RxBLService { protected S Service { get; } @@ -154,7 +154,7 @@ public abstract class CommandService : Command, IDisposable where S : IRxServ protected CommandService(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceState.EXCEPTION : ServiceState.COMMAND, LastException)); + _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -173,7 +173,7 @@ public void Dispose() } } - public abstract class CommandService : Command, IDisposable where S : IRxService + public abstract class CommandService : Command, IDisposable where S : RxBLService { protected S Service { get; } @@ -182,7 +182,7 @@ public abstract class CommandService : Command, IDisposable where S : I protected CommandService(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceState.EXCEPTION : ServiceState.COMMAND, LastException)); + _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -400,7 +400,7 @@ public override bool HasProgress() } } - public abstract class CommandServiceAsync : CommandAsync, IDisposable where S : IRxService + public abstract class CommandServiceAsync : CommandAsync, IDisposable where S : RxBLService { protected S Service { get; } @@ -409,7 +409,7 @@ public abstract class CommandServiceAsync : CommandAsync, IDisposable where S protected CommandServiceAsync(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceState.EXCEPTION : ServiceState.COMMAND, LastException)); + _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -428,7 +428,7 @@ public void Dispose() } } - public abstract class CommandServiceAsync : CommandAsync, IDisposable where S : IRxService + public abstract class CommandServiceAsync : CommandAsync, IDisposable where S : RxBLService { protected S Service { get; } @@ -437,7 +437,7 @@ public abstract class CommandServiceAsync : CommandAsync, IDisposable w protected CommandServiceAsync(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceState.EXCEPTION : ServiceState.COMMAND, LastException)); + _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -457,7 +457,7 @@ public void Dispose() } } - public abstract class CommandLongRunningServiceAsync : CommandServiceAsync where S : IRxService + public abstract class CommandLongRunningServiceAsync : CommandServiceAsync where S : RxBLService { protected CommandLongRunningServiceAsync(S service) : base(service) { @@ -474,7 +474,7 @@ public override bool HasProgress() } } - public abstract class CommandLongRunningServiceAsync : CommandServiceAsync where S : IRxService + public abstract class CommandLongRunningServiceAsync : CommandServiceAsync where S : RxBLService { protected CommandLongRunningServiceAsync(S service) : base(service) { diff --git a/RxBlazorLightCore/Core/Input.cs b/RxBlazorLightCore/Core/Input.cs index ae60adc..fc0bb20 100644 --- a/RxBlazorLightCore/Core/Input.cs +++ b/RxBlazorLightCore/Core/Input.cs @@ -1,47 +1,54 @@ - +using System.Reactive.Linq; using System.Reactive.Subjects; -using System.Reactive.Linq; namespace RxBlazorLightCore { public class InputBase : IObservable { - public T Value { get; internal set; } + public T Value + { + get + { + return _value; + } + set + { + SetValue(value); + } + } private readonly Subject _changedSubject; private readonly IObservable _changedObservable; + private T _value; protected InputBase(T value) { - Value = value; + _value = value; _changedSubject = new(); _changedObservable = _changedSubject.Publish().RefCount(); - } - protected virtual void OnValueChanging(T oldValue, T newValue) - { - } - - public void SetInitialValue(T value) - { - SetValueIntern(value, true); + _changedObservable + .Select(async newValue => + { + OnValueChanged(_value, newValue); + await OnValueChangedAsync(_value, newValue); + _value = newValue; + return _value; + }) + .Subscribe(); } - public void SetValue(T value) + protected virtual void OnValueChanged(T oldValue, T newValue) { } + protected virtual ValueTask OnValueChangedAsync(T oldValue, T newValue) { - SetValueIntern(value, false); + return ValueTask.CompletedTask; } - private void SetValueIntern(T value, bool init) + private void SetValue(T value) { - if (init || CanChange()) + if (CanChange()) { - if (!init) - { - OnValueChanging(Value, value); - } - Value = value; - Changed(Value); + _changedSubject.OnNext(value); } } @@ -50,20 +57,15 @@ public virtual bool CanChange() return true; } - protected void Changed(T value) - { - _changedSubject.OnNext(value); - } - public IDisposable Subscribe(IObserver observer) { return _changedObservable - .StartWith(Value) + .StartWith(_value) .Subscribe(observer); } } - public class InputBase : InputBase, IDisposable where S : IRxService + public class InputBase : InputBase, IDisposable where S : RxBLService { protected S Service { get; } private IDisposable? _serviceDisposable; @@ -71,7 +73,7 @@ public class InputBase : InputBase, IDisposable where S : IRxService protected InputBase(S service, T value) : base(value) { Service = service; - _serviceDisposable = this.Subscribe(_ => Service.StateHasChanged(ServiceState.INPUT, null)); + _serviceDisposable = this.Subscribe(_ => Service.StateHasChanged(ServiceStateChanged.INPUT, null)); } protected virtual void Dispose(bool disposing) @@ -94,7 +96,7 @@ public class Input(T value) : InputBase(value), IInput { } - public class Input : InputBase, IInput where S : IRxService + public class Input : InputBase, IInput where S : RxBLService { protected Input(S service, T value) : base(service, value) { @@ -106,77 +108,6 @@ public static IInput Create(S service, T value) } } - public class InputAsync(T value) : InputBase(value), IInputAsync - { - protected virtual async Task OnValueChangingAsync(T oldValue, T newValue) - { - await Task.CompletedTask; - } - - public async Task SetInitialValueAsync(T value) - { - await SetValueAsyncIntern(value, true); - } - - public async Task SetValueAsync(T value) - { - await SetValueAsyncIntern(value, false); - } - - private async Task SetValueAsyncIntern(T value, bool init) - { - if (init || CanChange()) - { - if (!init) - { - await OnValueChangingAsync(Value, value); - } - Value = value; - Changed(Value); - } - } - } - - public class InputAsync : InputBase, IInputAsync where S : IRxService - { - protected InputAsync(S service, T value) : base(service, value) - { - } - - public static IInputAsync Create(S service, T value) - { - return new InputAsync(service, value); - } - - protected virtual async Task OnValueChangingAsync(T oldValue, T newValue) - { - await Task.CompletedTask; - } - - public async Task SetInitialValueAsync(T value) - { - await SetValueAsyncIntern(value, true); - } - - public async Task SetValueAsync(T value) - { - await SetValueAsyncIntern(value, false); - } - - private async Task SetValueAsyncIntern(T value, bool init) - { - if (init || CanChange()) - { - if (!init) - { - await OnValueChangingAsync(Value, value); - } - Value = value; - Changed(Value); - } - } - } - public abstract class InputGroup : Input, IInputGroup { @@ -186,17 +117,13 @@ protected InputGroup(T value) : base(value) public abstract T[] GetItems(); - public virtual void Initialize() - { - } - public virtual bool IsItemDisabled(int index) { return false; } } - public abstract class InputGroup : Input, IInputGroup where S : IRxService + public abstract class InputGroup : Input, IInputGroup where S : RxBLService { protected InputGroup(S service, T value) : base(service, value) @@ -205,117 +132,9 @@ protected InputGroup(S service, T value) : base(service, value) public abstract T[] GetItems(); - public virtual void Initialize() - { - } - public virtual bool IsItemDisabled(int index) { return false; } } - - public abstract class InputGroupP : InputGroup, IInputGroup - { - protected P? Parameter { get; private set; } - - protected InputGroupP(T value) : base(value) - { - } - - public void SetParameter(P parameter) - { - Parameter = parameter; - } - } - - public abstract class InputGroupP : InputGroup, IInputGroup where S : IRxService - { - protected P? Parameter { get; private set; } - - protected InputGroupP(S service, T value) : base(service, value) - { - } - - public void SetParameter(P parameter) - { - Parameter = parameter; - } - } - - public abstract class InputGroupAsync : InputAsync, IInputGroupAsync - { - - protected InputGroupAsync(T value) : base(value) - { - } - - public abstract T[] GetItems(); - - public virtual void Initialize() - { - } - - public virtual Task InitializeAsync() - { - return Task.CompletedTask; - } - - public virtual bool IsItemDisabled(int index) - { - return false; - } - } - - public abstract class InputGroupAsync : InputAsync, IInputGroupAsync where S : IRxService - { - - protected InputGroupAsync(S service, T value) : base(service, value) - { - } - - public abstract T[] GetItems(); - - public virtual void Initialize() - { - } - - public virtual Task InitializeAsync() - { - return Task.CompletedTask; - } - - public virtual bool IsItemDisabled(int index) - { - return false; - } - } - - public abstract class InputGroupPAsync : InputGroupAsync, IInputGroupAsync - { - protected P? Parameter { get; private set; } - - protected InputGroupPAsync(T value) : base(value) - { - } - - public void SetParameter(P parameter) - { - Parameter = parameter; - } - } - - public abstract class InputGroupPAsync : InputGroupAsync, IInputGroupAsync where S : IRxService - { - protected P? Parameter { get; private set; } - - protected InputGroupPAsync(S service, T value) : base(service, value) - { - } - - public void SetParameter(P parameter) - { - Parameter = parameter; - } - } } \ No newline at end of file diff --git a/RxBlazorLightCore/Core/Interfaces.cs b/RxBlazorLightCore/Core/Interfaces.cs index f2c9a06..773c765 100644 --- a/RxBlazorLightCore/Core/Interfaces.cs +++ b/RxBlazorLightCore/Core/Interfaces.cs @@ -1,60 +1,44 @@  namespace RxBlazorLightCore { - public enum ServiceState + internal enum ServiceStateChanged { - SERVICE, COMMAND, EXCEPTION, - INPUT + INPUT, + SERVICE } - public interface IRxService + public interface IRxBLScope { - public ValueTask OnContextInitialized(); + public void EnterScope() { } + + public void LeaveScope() { } + } - public void OnContextDisposed(); + public interface IRxBLService + { + public ValueTask OnContextReadyAsync(); + public bool Initialized { get; } public IEnumerable Exceptions { get; } public void ResetExceptions(); - internal IDisposable Subscribe(Action stateHasChanged, double sampleMS); - internal void StateHasChanged(ServiceState reason, Exception? exception); + public IRxBLScope CreateScope(); + public IDisposable Subscribe(Action stateHasChanged, double sampleMS); } public interface IInput : IObservable { - public T Value { get; } - public void SetValue(T value); + public T Value { get; set; } public bool CanChange(); } - public interface IInputAsync : IInput - { - public Task SetValueAsync(T value); - } - public interface IInputGroup : IInput { public T[] GetItems(); - public void Initialize(); public bool IsItemDisabled(int index); } - public interface IInputGroup : IInputGroup - { - public void SetParameter(P parameter); - } - - public interface IInputGroupAsync : IInputGroup, IInputAsync - { - public Task InitializeAsync(); - } - - public interface IInputGroupAsync : IInputGroupAsync - { - public void SetParameter(P parameter); - } - public enum CommandState { NONE, diff --git a/RxBlazorLightCore/Core/ServiceBase.cs b/RxBlazorLightCore/Core/Service.cs similarity index 63% rename from RxBlazorLightCore/Core/ServiceBase.cs rename to RxBlazorLightCore/Core/Service.cs index fe1bde5..7dbcf7a 100644 --- a/RxBlazorLightCore/Core/ServiceBase.cs +++ b/RxBlazorLightCore/Core/Service.cs @@ -4,30 +4,33 @@ namespace RxBlazorLightCore { - public class RxBLServiceBase : IRxService + public abstract class RxBLService : IRxBLService { + public bool Initialized { get; private set; } + public IEnumerable Exceptions => _serviceExceptions; private readonly Subject _changedSubject = new(); private readonly IObservable _changedObservable; private readonly List _serviceExceptions; - private bool _contextInitialized; - public RxBLServiceBase() + public RxBLService() { _changedObservable = _changedSubject.Publish().RefCount(); _serviceExceptions = []; - _contextInitialized = false; + Initialized = false; } - public void StateHasChanged(ServiceState reason = ServiceState.SERVICE, Exception? exception = null) + public abstract IRxBLScope CreateScope(); + + internal void StateHasChanged(ServiceStateChanged reason = ServiceStateChanged.SERVICE, Exception? exception = null) { - if (exception is null && reason is ServiceState.EXCEPTION || - exception is not null && reason is not ServiceState.EXCEPTION) + if (exception is null && reason is ServiceStateChanged.EXCEPTION || + exception is not null && reason is not ServiceStateChanged.EXCEPTION) { throw new ArgumentException(reason.ToString()); } - if (reason is ServiceState.EXCEPTION && exception is not null) + if (reason is ServiceStateChanged.EXCEPTION && exception is not null) { _serviceExceptions.Add(exception); } @@ -42,25 +45,26 @@ public IDisposable Subscribe(Action stateHasChanged, double sampleMS = 100) .Subscribe(_ => stateHasChanged()); } - public ValueTask OnContextInitialized() + public async ValueTask OnContextReadyAsync() { - if (_contextInitialized) + if (Initialized) { throw new InvalidOperationException("Nested RxBLService context not allowed!"); } - _contextInitialized = true; - return InitializeContext(); + Initialized = true; + await InitializeContextAsync(); + StateHasChanged(); } - protected virtual ValueTask InitializeContext() + protected virtual ValueTask InitializeContextAsync() { return ValueTask.CompletedTask; } - public void OnContextDisposed() + public void OnContextDisposed() { DisposeContext(); - _contextInitialized = false; + Initialized = false; } protected virtual void DisposeContext() @@ -72,14 +76,9 @@ public void ResetExceptions() _serviceExceptions.Clear(); } - protected static IInput CreateInput(S service, T value) where S : IRxService + protected static IInput CreateInput(S service, T value) where S : RxBLService { return Input.Create(service, value); } - - protected static IInputAsync CreateInputAsync(S service, T value) where S : IRxService - { - return InputAsync.Create(service, value); - } } } diff --git a/RxBlazorLightCore/Core/ServiceExtensions.cs b/RxBlazorLightCore/Core/ServiceExtensions.cs index de6070c..2039522 100644 --- a/RxBlazorLightCore/Core/ServiceExtensions.cs +++ b/RxBlazorLightCore/Core/ServiceExtensions.cs @@ -1,30 +1,55 @@  using Microsoft.AspNetCore.Components; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; namespace RxBlazorLightCore { + public class RxServiceCollector + { + public IEnumerable Services => _services; + + private readonly List _services = []; + + public void AddService(T service) where T : IRxBLService + { + _services.Add(service); + } + } + public static class ServiceExtensions { - public static void AddRxBLService(this IServiceCollection services, double sampleMS = 100) where T : RxBLServiceBase + public static IServiceCollection AddRxBLService(this IServiceCollection services, double sampleMS = 100) where T : RxBLService, new() { + services.TryAddSingleton(); + services.AddCascadingValue(sp => { - var service = sp.GetRequiredService(); + var collector = sp.GetRequiredService(); + var service = new T(); + collector.AddService(service); return service.CreateCascadingValueSource(sampleMS); }); + + return services; } - public static void AddRxBLService(this IServiceCollection services, Func serviceFactory, double sampleMS = 100) where T : RxBLServiceBase + public static IServiceCollection AddRxBLService(this IServiceCollection services, Func serviceFactory, double sampleMS = 100) where T : RxBLService { + services.TryAddSingleton(); + services.AddCascadingValue(sp => { + var collector = sp.GetRequiredService(); var service = serviceFactory(sp); + collector.AddService(service); return service.CreateCascadingValueSource(sampleMS); }); + + return services; } - private static CascadingValueSource CreateCascadingValueSource(this T service, double sampleMS) where T : RxBLServiceBase + private static CascadingValueSource CreateCascadingValueSource(this T service, double sampleMS) where T : IRxBLService { var source = new CascadingValueSource(service, false); service.Subscribe(() => source.NotifyChangedAsync(), sampleMS); diff --git a/RxMudBlazorLight/ButtonBase/ButtonAsyncPRx.cs b/RxMudBlazorLight/ButtonBase/ButtonAsyncPRx.cs index 1f2c0ed..f81ad04 100644 --- a/RxMudBlazorLight/ButtonBase/ButtonAsyncPRx.cs +++ b/RxMudBlazorLight/ButtonBase/ButtonAsyncPRx.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Components.Web; using MudBlazor; using RxBlazorLightCore; -using RxMudBlazorLight.Extensions; using System.Diagnostics.CodeAnalysis; namespace RxMudBlazorLight.ButtonBase diff --git a/RxMudBlazorLight/ButtonBase/ButtonAsyncRx.cs b/RxMudBlazorLight/ButtonBase/ButtonAsyncRx.cs index 525ea37..ea4e555 100644 --- a/RxMudBlazorLight/ButtonBase/ButtonAsyncRx.cs +++ b/RxMudBlazorLight/ButtonBase/ButtonAsyncRx.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Components.Web; using MudBlazor; using RxBlazorLightCore; -using RxMudBlazorLight.Extensions; using System.Diagnostics.CodeAnalysis; namespace RxMudBlazorLight.ButtonBase diff --git a/RxMudBlazorLight/Buttons/MudButtonAsyncPRx.razor b/RxMudBlazorLight/Buttons/MudButtonAsyncPRx.razor index 0c0c70d..67b7e1c 100644 --- a/RxMudBlazorLight/Buttons/MudButtonAsyncPRx.razor +++ b/RxMudBlazorLight/Buttons/MudButtonAsyncPRx.razor @@ -5,7 +5,7 @@ @code { [Parameter, EditorRequired] - public required Func> RxCommandAsyncFactory { get; init; } + public required ICommandAsync RxCommandAsync { get; init; } [Parameter] public T? Parameter { get; set; } @@ -25,17 +25,12 @@ [Parameter] public Color? CancelColor { get; set; } - public ICommandAsync? RxCommandAsync { get; private set; } - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonAsyncPRX? _buttonAsyncPRX; private Color _buttonColor; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandAsyncFactory); - RxCommandAsync = RxCommandAsyncFactory(); - _buttonAsyncPRX = ButtonAsyncPRX.Create(MBButtonType.DEFAULT, Color, ChildContent, RxCommandAsync, BeforeExecution, AfterExecution, CancelText, CancelColor); _buttonColor = Color; diff --git a/RxMudBlazorLight/Buttons/MudButtonAsyncRx.razor b/RxMudBlazorLight/Buttons/MudButtonAsyncRx.razor index 1b598b3..ea7cb69 100644 --- a/RxMudBlazorLight/Buttons/MudButtonAsyncRx.razor +++ b/RxMudBlazorLight/Buttons/MudButtonAsyncRx.razor @@ -4,7 +4,7 @@ @code { [Parameter, EditorRequired] - public required Func? RxCommandAsyncFactory { get; init; } + public required ICommandAsync RxCommandAsync { get; init; } [Parameter] public Func>? PrepareExecutionAsync { get; set; } @@ -21,16 +21,11 @@ [Parameter] public Color? CancelColor { get; set; } - public ICommandAsync? RxCommandAsync { get; private set; } - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonAsyncRX? _buttonAsyncRX; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandAsyncFactory); - RxCommandAsync = RxCommandAsyncFactory(); - _buttonAsyncRX = ButtonAsyncRX.Create(MBButtonType.DEFAULT, Color, ChildContent, RxCommandAsync, BeforeExecution, AfterExecution, CancelText, CancelColor); base.OnInitialized(); diff --git a/RxMudBlazorLight/Buttons/MudButtonPRx.razor b/RxMudBlazorLight/Buttons/MudButtonPRx.razor index 508d6d5..69f2aaf 100644 --- a/RxMudBlazorLight/Buttons/MudButtonPRx.razor +++ b/RxMudBlazorLight/Buttons/MudButtonPRx.razor @@ -5,7 +5,7 @@ @code { [Parameter, EditorRequired] - public required Func> RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public T? Parameter { get; set; } @@ -24,14 +24,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonPRX? _buttonPRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonPRX = ButtonPRX.Create(MBButtonType.DEFAULT, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonPRX = ButtonPRX.Create(MBButtonType.DEFAULT, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); base.OnInitialized(); } @@ -39,12 +35,12 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(_buttonPRX); - ArgumentNullException.ThrowIfNull(_rxCommand); + ArgumentNullException.ThrowIfNull(RxCommand); - _rxCommand.PrepareExecution = PrepareExecution; + RxCommand.PrepareExecution = PrepareExecution; _buttonPRX.SetParameters(Parameter); - Disabled = !_rxCommand.CanExecute(Parameter); + Disabled = !RxCommand.CanExecute(Parameter); OnClick = _buttonPRX.OnClick; base.OnParametersSet(); diff --git a/RxMudBlazorLight/Buttons/MudButtonRx.razor b/RxMudBlazorLight/Buttons/MudButtonRx.razor index 750337f..815943a 100644 --- a/RxMudBlazorLight/Buttons/MudButtonRx.razor +++ b/RxMudBlazorLight/Buttons/MudButtonRx.razor @@ -4,7 +4,7 @@ @code { [Parameter, EditorRequired] - public required Func RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public Func? PrepareExecution { get; set; } @@ -20,14 +20,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonRX? _buttonRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonRX = ButtonRX.Create(MBButtonType.DEFAULT, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonRX = ButtonRX.Create(MBButtonType.DEFAULT, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); OnClick = _buttonRX.OnClick; base.OnInitialized(); @@ -35,10 +31,8 @@ protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(_rxCommand); - - _rxCommand.PrepareExecution = PrepareExecution; - Disabled = !_rxCommand.CanExecute(); + RxCommand.PrepareExecution = PrepareExecution; + Disabled = !RxCommand.CanExecute(); base.OnParametersSet(); } } diff --git a/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor b/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor index c1d217f..fd9aef1 100644 --- a/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor +++ b/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor @@ -8,7 +8,7 @@ @CancelButton RxCommandAsync!) Parameter=@Parameter + T=@T RxCommandAsync=@RxCommandAsync Parameter=@Parameter PrepareExecutionAsync=@(PrepareExecutionAsync!) BeforeExecution=@BeforeExecutionDo AfterExecution=@AfterExecutionDo CancelColor=@CancelColor CancelText=@CancelText> diff --git a/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs b/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs index 1a90616..9069e73 100644 --- a/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs +++ b/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs @@ -43,7 +43,7 @@ public partial class DialogAsyncPRx : ComponentBase [Parameter] public Color? CancelColor { get; set; } - private MudButtonAsyncPRx? _buttonRef; + private MudButtonAsyncPRx? _buttonRef; private IDisposable? _buttonDisposable; private bool _canceled = false; diff --git a/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor b/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor index 31b6e9e..1129d9d 100644 --- a/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor +++ b/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor @@ -7,7 +7,7 @@ Cancel RxCommandAsync) PrepareExecutionAsync=@(PrepareExecutionAsync!) + RxCommandAsync=@RxCommandAsync PrepareExecutionAsync=@(PrepareExecutionAsync!) BeforeExecution=@BeforeExecutionDo AfterExecution=@AfterExecutionDo CancelColor=@CancelColor CancelText=@CancelText> @ConfirmButton diff --git a/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs b/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs index 1ab81b6..7a83f4d 100644 --- a/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs +++ b/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs @@ -101,7 +101,7 @@ private void BeforeExecutionDo() _buttonDisposable = _buttonRef.RxCommandAsync.Subscribe(cs => { InvokeAsync(StateHasChanged); - _canceled = cs is CommandState.CANCELED; + _canceled = cs is CommandState.CANCELED; }); } diff --git a/RxMudBlazorLight/FabButtons/MudFabAsyncPRx.razor b/RxMudBlazorLight/FabButtons/MudFabAsyncPRx.razor index 3a563b3..53cd6ba 100644 --- a/RxMudBlazorLight/FabButtons/MudFabAsyncPRx.razor +++ b/RxMudBlazorLight/FabButtons/MudFabAsyncPRx.razor @@ -7,7 +7,7 @@ @code { [Parameter, EditorRequired] - public required Func> RxCommandAsyncFactory { get; init; } + public required ICommandAsync RxCommandAsync { get; init; } [Parameter] public T? Parameter { get; set; } @@ -33,14 +33,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonAsyncPRX? _buttonAsyncPRX; private Color _buttonColor; - private ICommandAsync? _rxCommandAsync; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandAsyncFactory); - _rxCommandAsync = RxCommandAsyncFactory(); - - _buttonAsyncPRX = ButtonAsyncPRX.Create(MBButtonType.FAB, Color, null, _rxCommandAsync, BeforeExecution, AfterExecution, CancelText, null); + _buttonAsyncPRX = ButtonAsyncPRX.Create(MBButtonType.FAB, Color, null, RxCommandAsync, BeforeExecution, AfterExecution, CancelText, null); _buttonColor = Color; base.OnInitialized(); @@ -49,9 +45,8 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(_buttonAsyncPRX); - ArgumentNullException.ThrowIfNull(_rxCommandAsync); - _rxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; + RxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; _buttonAsyncPRX.SetParameters(Parameter); var parameters = _buttonAsyncPRX.GetFabParameters(StartIcon, EndIcon, Label, IconVariant); @@ -68,7 +63,7 @@ private string GetProgressIcon() { - if (_rxCommandAsync is not null && CancelText is null && _rxCommandAsync.HasProgress() && _rxCommandAsync.Executing()) + if (CancelText is null && RxCommandAsync.HasProgress() && RxCommandAsync.Executing()) { return IconVariant.GetProgressIcon(); } diff --git a/RxMudBlazorLight/FabButtons/MudFabAsyncRx.razor b/RxMudBlazorLight/FabButtons/MudFabAsyncRx.razor index c7c3a4d..af0fa86 100644 --- a/RxMudBlazorLight/FabButtons/MudFabAsyncRx.razor +++ b/RxMudBlazorLight/FabButtons/MudFabAsyncRx.razor @@ -6,7 +6,7 @@ @code { [Parameter, EditorRequired] - public required Func? RxCommandAsyncFactory { get; init; } + public required ICommandAsync RxCommandAsync { get; init; } [Parameter] public Func>? PrepareExecutionAsync { get; set; } @@ -30,14 +30,10 @@ private ButtonAsyncRX? _buttonAsyncRX; private string? _buttonStartIcon; private string? _buttonEndIcon; - private ICommandAsync? _rxCommandAsync; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandAsyncFactory); - _rxCommandAsync = RxCommandAsyncFactory(); - - _buttonAsyncRX = ButtonAsyncRX.Create(MBButtonType.FAB, Color, null, _rxCommandAsync, BeforeExecution, AfterExecution, CancelText, CancelColor); + _buttonAsyncRX = ButtonAsyncRX.Create(MBButtonType.FAB, Color, null, RxCommandAsync, BeforeExecution, AfterExecution, CancelText, CancelColor); _buttonStartIcon = StartIcon; _buttonEndIcon = EndIcon; @@ -47,9 +43,8 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(_buttonAsyncRX); - ArgumentNullException.ThrowIfNull(_rxCommandAsync); - _rxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; + RxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; _buttonAsyncRX.SetParameters(); var parameters = _buttonAsyncRX.GetFabParameters(StartIcon, EndIcon, Label, IconVariant); @@ -66,7 +61,7 @@ private string GetProgressIcon() { - if (_rxCommandAsync is not null && CancelText is null && _rxCommandAsync.HasProgress() && _rxCommandAsync.Executing()) + if (CancelText is null && RxCommandAsync.HasProgress() && RxCommandAsync.Executing()) { return IconVariant.GetProgressIcon(); } diff --git a/RxMudBlazorLight/FabButtons/MudFabPRx.razor b/RxMudBlazorLight/FabButtons/MudFabPRx.razor index 008407f..75bdab5 100644 --- a/RxMudBlazorLight/FabButtons/MudFabPRx.razor +++ b/RxMudBlazorLight/FabButtons/MudFabPRx.razor @@ -5,7 +5,7 @@ @code { [Parameter, EditorRequired] - public required Func> RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public T? Parameter { get; set; } @@ -24,14 +24,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonPRX? _buttonPRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonPRX = ButtonPRX.Create(MBButtonType.FAB, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonPRX = ButtonPRX.Create(MBButtonType.FAB, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); base.OnInitialized(); } @@ -39,12 +35,11 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(_buttonPRX); - ArgumentNullException.ThrowIfNull(_rxCommand); - _rxCommand.PrepareExecution = PrepareExecution; + RxCommand.PrepareExecution = PrepareExecution; _buttonPRX.SetParameters(Parameter); - Disabled = !_rxCommand.CanExecute(Parameter); + Disabled = !RxCommand.CanExecute(Parameter); OnClick = _buttonPRX.OnClick; base.OnParametersSet(); diff --git a/RxMudBlazorLight/FabButtons/MudFabRx.razor b/RxMudBlazorLight/FabButtons/MudFabRx.razor index a202cc6..57109dc 100644 --- a/RxMudBlazorLight/FabButtons/MudFabRx.razor +++ b/RxMudBlazorLight/FabButtons/MudFabRx.razor @@ -4,7 +4,7 @@ @code { [Parameter, EditorRequired] - public required Func RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public Func? PrepareExecution { get; set; } @@ -20,14 +20,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonRX? _buttonRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonRX = ButtonRX.Create(MBButtonType.FAB, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonRX = ButtonRX.Create(MBButtonType.FAB, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); OnClick = _buttonRX.OnClick; base.OnInitialized(); @@ -35,10 +31,8 @@ protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(_rxCommand); - - _rxCommand.PrepareExecution = PrepareExecution; - Disabled = !_rxCommand.CanExecute(); + RxCommand.PrepareExecution = PrepareExecution; + Disabled = !RxCommand.CanExecute(); base.OnParametersSet(); } } diff --git a/RxMudBlazorLight/IconButtons/MudIconButtonAsyncPRx.razor b/RxMudBlazorLight/IconButtons/MudIconButtonAsyncPRx.razor index 9bdade0..45dd18c 100644 --- a/RxMudBlazorLight/IconButtons/MudIconButtonAsyncPRx.razor +++ b/RxMudBlazorLight/IconButtons/MudIconButtonAsyncPRx.razor @@ -6,8 +6,8 @@ @code { - [Parameter, EditorRequired] - public required Func> RxCommandAsyncFactory { get; init; } + [Parameter] + public required ICommandAsync RxCommandAsync { get; set; } [Parameter] public T? Parameter { get; set; } @@ -27,13 +27,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonAsyncPRX? _buttonAsyncPRX; private Color _buttonColor; - private ICommandAsync? _rxCommandAsync; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandAsyncFactory); - _rxCommandAsync = RxCommandAsyncFactory(); - _buttonAsyncPRX = ButtonAsyncPRX.Create(MBButtonType.ICON, Color, null, _rxCommandAsync, BeforeExecution, AfterExecution, null, null); + _buttonAsyncPRX = ButtonAsyncPRX.Create(MBButtonType.ICON, Color, null, RxCommandAsync, BeforeExecution, AfterExecution, null, null); _buttonColor = Color; base.OnInitialized(); @@ -47,10 +44,9 @@ } ArgumentNullException.ThrowIfNull(_buttonAsyncPRX); - ArgumentNullException.ThrowIfNull(_rxCommandAsync); ArgumentNullException.ThrowIfNull(Icon); - _rxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; + RxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; _buttonAsyncPRX.SetParameters(Parameter); Icon = _buttonAsyncPRX.GetIconButtonParameters(Icon, IconVariant); @@ -63,7 +59,7 @@ private string GetProgressIcon() { - if (_rxCommandAsync is not null && _rxCommandAsync.HasProgress() && _rxCommandAsync.Executing()) + if (RxCommandAsync.HasProgress() && RxCommandAsync.Executing()) { return IconVariant.GetProgressIcon(); } diff --git a/RxMudBlazorLight/IconButtons/MudIconButtonAsyncRx.razor b/RxMudBlazorLight/IconButtons/MudIconButtonAsyncRx.razor index 07d2e8d..af61b25 100644 --- a/RxMudBlazorLight/IconButtons/MudIconButtonAsyncRx.razor +++ b/RxMudBlazorLight/IconButtons/MudIconButtonAsyncRx.razor @@ -6,7 +6,7 @@ @code { [Parameter, EditorRequired] - public required Func? RxCommandAsyncFactory { get; init; } + public required ICommandAsync RxCommandAsync { get; init; } [Parameter] public Func>? PrepareExecutionAsync { get; set; } @@ -22,13 +22,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonAsyncRX? _buttonAsyncRX; - private ICommandAsync? _rxCommandAsync; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandAsyncFactory); - _rxCommandAsync = RxCommandAsyncFactory(); - _buttonAsyncRX = ButtonAsyncRX.Create(MBButtonType.ICON, Color, ChildContent, _rxCommandAsync, BeforeExecution, AfterExecution, null, null); + _buttonAsyncRX = ButtonAsyncRX.Create(MBButtonType.ICON, Color, ChildContent, RxCommandAsync, BeforeExecution, AfterExecution, null, null); base.OnInitialized(); } @@ -41,10 +38,9 @@ } ArgumentNullException.ThrowIfNull(_buttonAsyncRX); - ArgumentNullException.ThrowIfNull(_rxCommandAsync); ArgumentNullException.ThrowIfNull(Icon); - _rxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; + RxCommandAsync.PrepareExecutionAsync = PrepareExecutionAsync; _buttonAsyncRX.SetParameters(); Icon = _buttonAsyncRX.GetIconButtonParameters(Icon, IconVariant); @@ -57,7 +53,7 @@ private string GetProgressIcon() { - if (_rxCommandAsync is not null && _rxCommandAsync.HasProgress() && _rxCommandAsync.Executing()) + if (RxCommandAsync.HasProgress() && RxCommandAsync.Executing()) { return IconVariant.GetProgressIcon(); } diff --git a/RxMudBlazorLight/IconButtons/MudIconButtonPRx.razor b/RxMudBlazorLight/IconButtons/MudIconButtonPRx.razor index ca8dd35..d283a9b 100644 --- a/RxMudBlazorLight/IconButtons/MudIconButtonPRx.razor +++ b/RxMudBlazorLight/IconButtons/MudIconButtonPRx.razor @@ -5,7 +5,7 @@ @code { [Parameter, EditorRequired] - public required Func> RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public T? Parameter { get; set; } @@ -24,14 +24,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonPRX? _buttonPRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonPRX = ButtonPRX.Create(MBButtonType.ICON, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonPRX = ButtonPRX.Create(MBButtonType.ICON, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); base.OnInitialized(); } @@ -39,12 +35,11 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(_buttonPRX); - ArgumentNullException.ThrowIfNull(_rxCommand); - _rxCommand.PrepareExecution = PrepareExecution; + RxCommand.PrepareExecution = PrepareExecution; _buttonPRX.SetParameters(Parameter); - Disabled = !_rxCommand.CanExecute(Parameter); + Disabled = !RxCommand.CanExecute(Parameter); OnClick = _buttonPRX.OnClick; base.OnParametersSet(); diff --git a/RxMudBlazorLight/IconButtons/MudIconButtonRx.razor b/RxMudBlazorLight/IconButtons/MudIconButtonRx.razor index 14a1d4e..b8b480a 100644 --- a/RxMudBlazorLight/IconButtons/MudIconButtonRx.razor +++ b/RxMudBlazorLight/IconButtons/MudIconButtonRx.razor @@ -4,7 +4,7 @@ @code { [Parameter, EditorRequired] - public required Func RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public Func? PrepareExecution { get; set; } @@ -20,14 +20,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonRX? _buttonRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonRX = ButtonRX.Create(MBButtonType.ICON, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonRX = ButtonRX.Create(MBButtonType.ICON, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); OnClick = _buttonRX.OnClick; base.OnInitialized(); @@ -35,10 +31,8 @@ protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(_rxCommand); - - _rxCommand.PrepareExecution = PrepareExecution; - Disabled = !_rxCommand.CanExecute(); + RxCommand.PrepareExecution = PrepareExecution; + Disabled = !RxCommand.CanExecute(); base.OnParametersSet(); } } diff --git a/RxMudBlazorLight/Inputs/MudAutocompleteAsyncRx.razor b/RxMudBlazorLight/Inputs/MudAutocompleteAsyncRx.razor deleted file mode 100644 index db53911..0000000 --- a/RxMudBlazorLight/Inputs/MudAutocompleteAsyncRx.razor +++ /dev/null @@ -1,26 +0,0 @@ -@inherits MudAutocomplete -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - Value = RxInputAsync.Value; - ArgumentNullException.ThrowIfNull(Value); - - Text = Value.ToString(); - - ValueChanged = EventCallback.Factory.Create(this, v => RxInputAsync.SetValueAsync(v)); - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor b/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor index b58e54a..b71612d 100644 --- a/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor +++ b/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor @@ -4,21 +4,19 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(RxInput); - Value = RxInput.Value; ArgumentNullException.ThrowIfNull(Value); Text = Value.ToString(); - ValueChanged = EventCallback.Factory.Create(this, v => RxInput.SetValue(v)); + ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); Disabled = !RxInput.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/Inputs/MudCheckBoxAsyncRx.razor b/RxMudBlazorLight/Inputs/MudCheckBoxAsyncRx.razor deleted file mode 100644 index 55db43a..0000000 --- a/RxMudBlazorLight/Inputs/MudCheckBoxAsyncRx.razor +++ /dev/null @@ -1,29 +0,0 @@ -@inherits MudCheckBox -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - Value = RxInputAsync.Value; - ValueChanged = EventCallback.Factory.Create(this, v => - { - if (v is not null) - { - RxInputAsync.SetValueAsync(v); - } - }); - - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor b/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor index 1debe56..3704405 100644 --- a/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor +++ b/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor @@ -4,21 +4,19 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(RxInput); - Value = RxInput.Value; ValueChanged = EventCallback.Factory.Create(this, v => { if (v is not null) { - RxInput.SetValue(v); + RxInput.Value = v; } }); diff --git a/RxMudBlazorLight/Inputs/MudNumericFieldAsyncRx.razor b/RxMudBlazorLight/Inputs/MudNumericFieldAsyncRx.razor deleted file mode 100644 index e45884d..0000000 --- a/RxMudBlazorLight/Inputs/MudNumericFieldAsyncRx.razor +++ /dev/null @@ -1,31 +0,0 @@ -@inherits MudNumericField -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - [Parameter] - public Func>? InitialValueProviderAsync { get; set; } - - [Parameter] - public Func? InitialValueProvider { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - Value = RxInputAsync.Value; - ArgumentNullException.ThrowIfNull(Value); - - Text = Value.ToString(); - ValueChanged = EventCallback.Factory.Create(this, v => RxInputAsync.SetValueAsync(v)); - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor b/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor index 6f228f1..119e551 100644 --- a/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor +++ b/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor @@ -4,20 +4,18 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(RxInput); - Value = RxInput.Value; ArgumentNullException.ThrowIfNull(Value); Text = Value.ToString(); - ValueChanged = EventCallback.Factory.Create(this, v => RxInput.SetValue(v)); + ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); Disabled = !RxInput.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/Inputs/MudRatingAsyncRx.razor b/RxMudBlazorLight/Inputs/MudRatingAsyncRx.razor deleted file mode 100644 index 7917955..0000000 --- a/RxMudBlazorLight/Inputs/MudRatingAsyncRx.razor +++ /dev/null @@ -1,21 +0,0 @@ -@inherits MudRating - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - SelectedValue = RxInputAsync.Value; - SelectedValueChanged = EventCallback.Factory.Create(this, v => RxInputAsync.SetValueAsync(v)); - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudRatingRx.razor b/RxMudBlazorLight/Inputs/MudRatingRx.razor index 1de714c..fc18954 100644 --- a/RxMudBlazorLight/Inputs/MudRatingRx.razor +++ b/RxMudBlazorLight/Inputs/MudRatingRx.razor @@ -3,17 +3,21 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - protected override void OnParametersSet() + protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxInput); + base.OnInitialized(); + + SelectedValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); + } + protected override void OnParametersSet() + { SelectedValue = RxInput.Value; - SelectedValueChanged = EventCallback.Factory.Create(this, v => RxInput.SetValue(v)); Disabled = !RxInput.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/Inputs/MudSliderAsyncRx.razor b/RxMudBlazorLight/Inputs/MudSliderAsyncRx.razor deleted file mode 100644 index c6124cb..0000000 --- a/RxMudBlazorLight/Inputs/MudSliderAsyncRx.razor +++ /dev/null @@ -1,22 +0,0 @@ -@inherits MudSlider -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - Value = RxInputAsync.Value; - ValueChanged = EventCallback.Factory.Create(this, v => RxInputAsync.SetValueAsync(v)); - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudSliderRx.razor b/RxMudBlazorLight/Inputs/MudSliderRx.razor index 01795de..1b1debe 100644 --- a/RxMudBlazorLight/Inputs/MudSliderRx.razor +++ b/RxMudBlazorLight/Inputs/MudSliderRx.razor @@ -4,17 +4,15 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(RxInput); - Value = RxInput.Value; - ValueChanged = EventCallback.Factory.Create(this, v => RxInput.SetValue(v)); + ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); Disabled = !RxInput.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/Inputs/MudSwitchAsyncRx.razor b/RxMudBlazorLight/Inputs/MudSwitchAsyncRx.razor deleted file mode 100644 index cedb31a..0000000 --- a/RxMudBlazorLight/Inputs/MudSwitchAsyncRx.razor +++ /dev/null @@ -1,29 +0,0 @@ -@inherits MudSwitch -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - Value = RxInputAsync.Value; - ValueChanged = EventCallback.Factory.Create(this, v => - { - if (v is not null) - { - RxInputAsync.SetValueAsync(v); - } - }); - - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudSwitchRx.razor b/RxMudBlazorLight/Inputs/MudSwitchRx.razor index 9fb8ad2..e4e5b5a 100644 --- a/RxMudBlazorLight/Inputs/MudSwitchRx.razor +++ b/RxMudBlazorLight/Inputs/MudSwitchRx.razor @@ -4,21 +4,19 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(RxInput); - Value = RxInput.Value; ValueChanged = EventCallback.Factory.Create(this, v => { if (v is not null) { - RxInput.SetValue(v); + RxInput.Value = v; } }); diff --git a/RxMudBlazorLight/Inputs/MudTextFieldAsyncRx.razor b/RxMudBlazorLight/Inputs/MudTextFieldAsyncRx.razor deleted file mode 100644 index ce93b4a..0000000 --- a/RxMudBlazorLight/Inputs/MudTextFieldAsyncRx.razor +++ /dev/null @@ -1,26 +0,0 @@ -@inherits MudTextField -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public IInputAsync? RxInputAsync { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputAsync); - - Value = RxInputAsync.Value; - ArgumentNullException.ThrowIfNull(Value); - - Text = Value.ToString(); - - ValueChanged = EventCallback.Factory.Create(this, v => RxInputAsync.SetValueAsync(v)); - Disabled = !RxInputAsync.CanChange(); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/MudTextFieldRx.razor b/RxMudBlazorLight/Inputs/MudTextFieldRx.razor index fc8993e..ea48a4f 100644 --- a/RxMudBlazorLight/Inputs/MudTextFieldRx.razor +++ b/RxMudBlazorLight/Inputs/MudTextFieldRx.razor @@ -4,19 +4,22 @@ @RenderBase() @code { - [Parameter] - public IInput? RxInput { get; set; } + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - protected override void OnParametersSet() + protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxInput); + base.OnInitialized(); + ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); + } + protected override void OnParametersSet() + { Value = RxInput.Value; Text = Value?.ToString(); - ValueChanged = EventCallback.Factory.Create(this, v => RxInput.SetValue(v)); Disabled = !RxInput.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncBaseRx.cs b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncBaseRx.cs deleted file mode 100644 index 8a6a270..0000000 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncBaseRx.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Microsoft.AspNetCore.Components; -using MudBlazor; -using RxBlazorLightCore; - -namespace RxMudBlazorLight.Inputs.Radio -{ - public class MudRadioGroupAsyncBaseRx : MudRadioGroup - { - [Parameter] - public Func DenseCallback { get; set; } = _ => false; - - [Parameter] - public Func SizeCallback { get; set; } = _ => Size.Medium; - - [Parameter] - public Func ColorCallback { get; set; } = _ => Color.Default; - - [Parameter] - public Func PlacementCallback { get; set; } = _ => Placement.End; - - protected IInputGroupAsync? RxInputGroupAsyncBase { get; set; } - - private bool _initializedAsync = false; - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncBase); - - if (ChildContent is null) - { - RxInputGroupAsyncBase.Initialize(); - - var values = RxInputGroupAsyncBase.GetItems(); - - ChildContent = builder => - { - for (var i = 0; i < values.Length; i++) - { - builder.OpenComponent(0, typeof(MudRadioRx)); - builder.AddAttribute(1, "Index", i); - builder.AddAttribute(2, "Values", values); - builder.AddAttribute(3, "Dense", DenseCallback(values[i])); - builder.AddAttribute(4, "Size", SizeCallback(values[i])); - builder.AddAttribute(5, "Color", ColorCallback(values[i])); - builder.AddAttribute(6, "Placement", PlacementCallback(values[i])); - builder.AddAttribute(7, "Disabled", RxInputGroupAsyncBase.IsItemDisabled(i)); - builder.AddAttribute(8, "InitialSelection", RxInputGroupAsyncBase.Value); - builder.CloseComponent(); - } - }; - } - - Value = RxInputGroupAsyncBase.Value; - ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupAsyncBase.SetValueAsync(v)); - Disabled = !RxInputGroupAsyncBase.CanChange(); - - base.OnParametersSet(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncBase); - - if (!_initializedAsync && firstRender) - { - _initializedAsync = true; - await RxInputGroupAsyncBase.InitializeAsync(); - Value = RxInputGroupAsyncBase.Value; - } - - await base.OnAfterRenderAsync(firstRender); - } - } -} diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncPRx.razor b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncPRx.razor deleted file mode 100644 index 219bf76..0000000 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncPRx.razor +++ /dev/null @@ -1,36 +0,0 @@ -@inherits MudRadioGroupAsyncBaseRx -@typeparam T -@typeparam P - -@RenderBase() - -@code { - [Parameter] - public Func>? RxInputGroupAsyncFactory { get; set; } - - [Parameter] - public P? Parameter { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroupAsync? _rxInputGroupAsync; - - protected override void OnInitialized() - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncFactory); - - _rxInputGroupAsync = RxInputGroupAsyncFactory(); - RxInputGroupAsyncBase = _rxInputGroupAsync; - - base.OnInitialized(); - } - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(_rxInputGroupAsync); - ArgumentNullException.ThrowIfNull(Parameter); - - _rxInputGroupAsync.SetParameter(Parameter); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncRx.razor b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncRx.razor deleted file mode 100644 index ce6a4a1..0000000 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupAsyncRx.razor +++ /dev/null @@ -1,22 +0,0 @@ -@inherits MudRadioGroupAsyncBaseRx -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public Func>? RxInputGroupAsyncFactory { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroupAsync? _rxInputGroupAsync; - - protected override void OnInitialized() - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncFactory); - - _rxInputGroupAsync = RxInputGroupAsyncFactory(); - RxInputGroupAsyncBase = _rxInputGroupAsync; - - base.OnInitialized(); - } -} diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs index e8e0667..1042e28 100644 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs +++ b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs @@ -26,8 +26,6 @@ protected override void OnParametersSet() if (ChildContent is null) { - RxInputGroupBase.Initialize(); - var values = RxInputGroupBase.GetItems(); ChildContent = builder => @@ -49,7 +47,7 @@ protected override void OnParametersSet() } Value = RxInputGroupBase.Value; - ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.SetValue(v)); + ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.Value = v); Disabled = !RxInputGroupBase.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupPRx.razor b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupPRx.razor deleted file mode 100644 index f7eb0f0..0000000 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupPRx.razor +++ /dev/null @@ -1,36 +0,0 @@ -@inherits MudRadioGroupBaseRx -@typeparam T -@typeparam P - -@RenderBase() - -@code { - [Parameter] - public Func>? RxInputGroupFactory { get; set; } - - [Parameter] - public P? Parameter { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroup? _rxInputGroup; - - protected override void OnInitialized() - { - ArgumentNullException.ThrowIfNull(RxInputGroupFactory); - - _rxInputGroup = RxInputGroupFactory(); - RxInputGroupBase = _rxInputGroup; - - base.OnInitialized(); - } - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(Parameter); - ArgumentNullException.ThrowIfNull(_rxInputGroup); - - _rxInputGroup.SetParameter(Parameter); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor index af780e8..9269356 100644 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor +++ b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor @@ -4,17 +4,15 @@ @RenderBase() @code { - [Parameter] - public Func>? RxInputGroupFactory { get; set; } + [Parameter, EditorRequired] + public required IInputGroup RxInputGroup { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private IInputGroup? _rxInputGroup; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxInputGroupFactory); - - _rxInputGroup = RxInputGroupFactory(); + _rxInputGroup = RxInputGroup; RxInputGroupBase = _rxInputGroup; base.OnInitialized(); diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectAsyncBaseRx.cs b/RxMudBlazorLight/Inputs/Select/MudSelectAsyncBaseRx.cs deleted file mode 100644 index 4f34e4a..0000000 --- a/RxMudBlazorLight/Inputs/Select/MudSelectAsyncBaseRx.cs +++ /dev/null @@ -1,82 +0,0 @@ -using Microsoft.AspNetCore.Components; -using MudBlazor; -using RxBlazorLightCore; - -namespace RxMudBlazorLight.Inputs.Select -{ - public class MudSelectAsyncBaseRx : MudSelect - { - [Parameter] - public bool HideDisabled { get; set; } = false; - - protected IInputGroupAsync? RxInputGroupAsyncBase { get; set; } - - private bool _initialized = false; - private bool _initializedAsync = false; - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncBase); - - Value = RxInputGroupAsyncBase.Value; - Text = Value?.ToString(); - - ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupAsyncBase.SetValueAsync(v)); - Disabled = !RxInputGroupAsyncBase.CanChange(); - - if (ChildContent is null) - { - var values = RxInputGroupAsyncBase.GetItems(); - - ChildContent = builder => - { - for (var i = 0; i < values.Length; i++) - { - if (HideDisabled && RxInputGroupAsyncBase.IsItemDisabled(i)) - { - continue; - } - - builder.OpenComponent(0, typeof(MudSelectItemRx)); - builder.AddAttribute(1, "Index", i); - builder.AddAttribute(2, "Values", values); - builder.AddAttribute(3, "Disabled", RxInputGroupAsyncBase.IsItemDisabled(i)); - builder.CloseComponent(); - } - }; - } - - base.OnParametersSet(); - } - - protected override void OnAfterRender(bool firstRender) - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncBase); - - if (!_initialized && firstRender) - { - _initialized = true; - RxInputGroupAsyncBase.Initialize(); - Value = RxInputGroupAsyncBase.Value; - Text = Value?.ToString(); - } - - base.OnAfterRender(firstRender); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncBase); - - if (!_initializedAsync && firstRender) - { - _initializedAsync = true; - await RxInputGroupAsyncBase.InitializeAsync(); - Value = RxInputGroupAsyncBase.Value; - Text = Value?.ToString(); - } - - await base.OnAfterRenderAsync(firstRender); - } - } -} diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectAsyncPRx.razor b/RxMudBlazorLight/Inputs/Select/MudSelectAsyncPRx.razor deleted file mode 100644 index 65cb39d..0000000 --- a/RxMudBlazorLight/Inputs/Select/MudSelectAsyncPRx.razor +++ /dev/null @@ -1,36 +0,0 @@ -@inherits MudSelectAsyncBaseRx -@typeparam T -@typeparam P - -@RenderBase() - -@code { - [Parameter] - public Func>? RxInputGroupAsyncFactory { get; set; } - - [Parameter] - public P? Parameter { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroupAsync? _rxInputGroupAsync; - - protected override void OnInitialized() - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncFactory); - - _rxInputGroupAsync = RxInputGroupAsyncFactory(); - RxInputGroupAsyncBase = _rxInputGroupAsync; - - base.OnInitialized(); - } - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(_rxInputGroupAsync); - ArgumentNullException.ThrowIfNull(Parameter); - - _rxInputGroupAsync.SetParameter(Parameter); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectAsyncRx.razor b/RxMudBlazorLight/Inputs/Select/MudSelectAsyncRx.razor deleted file mode 100644 index f761d5e..0000000 --- a/RxMudBlazorLight/Inputs/Select/MudSelectAsyncRx.razor +++ /dev/null @@ -1,22 +0,0 @@ -@inherits MudSelectAsyncBaseRx -@typeparam T - -@RenderBase() - -@code { - [Parameter] - public Func>? RxInputGroupAsyncFactory { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroupAsync? _rxInputGroupAsync; - - protected override void OnInitialized() - { - ArgumentNullException.ThrowIfNull(RxInputGroupAsyncFactory); - - _rxInputGroupAsync = RxInputGroupAsyncFactory(); - RxInputGroupAsyncBase = _rxInputGroupAsync; - - base.OnInitialized(); - } -} diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs b/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs index 754a4aa..3e23db5 100644 --- a/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs +++ b/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs @@ -20,7 +20,7 @@ protected override void OnParametersSet() Value = RxInputGroupBase.Value; Text = Value?.ToString(); - ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.SetValue(v)); + ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.Value = v); Disabled = !RxInputGroupBase.CanChange(); if (ChildContent is null) @@ -55,7 +55,6 @@ protected override void OnAfterRender(bool firstRender) if (!_initialized && firstRender) { _initialized = true; - RxInputGroupBase.Initialize(); Value = RxInputGroupBase.Value; Text = Value?.ToString(); } diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectPRx.razor b/RxMudBlazorLight/Inputs/Select/MudSelectPRx.razor deleted file mode 100644 index 1df8d79..0000000 --- a/RxMudBlazorLight/Inputs/Select/MudSelectPRx.razor +++ /dev/null @@ -1,36 +0,0 @@ -@inherits MudSelectBaseRx -@typeparam T -@typeparam P - -@RenderBase() - -@code { - [Parameter] - public Func>? RxInputGroupFactory { get; set; } - - [Parameter] - public P? Parameter { get; set; } - - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroup? _rxInputGroup; - - protected override void OnInitialized() - { - ArgumentNullException.ThrowIfNull(RxInputGroupFactory); - - _rxInputGroup = RxInputGroupFactory(); - RxInputGroupBase = _rxInputGroup; - - base.OnInitialized(); - } - - protected override void OnParametersSet() - { - ArgumentNullException.ThrowIfNull(_rxInputGroup); - ArgumentNullException.ThrowIfNull(Parameter); - - _rxInputGroup.SetParameter(Parameter); - - base.OnParametersSet(); - } -} diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor b/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor index e62af4d..6624504 100644 --- a/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor +++ b/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor @@ -4,17 +4,15 @@ @RenderBase() @code { - [Parameter] - public Func>? RxInputGroupFactory { get; set; } + [Parameter, EditorRequired] + public required IInputGroup RxInputGroup { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private IInputGroup? _rxInputGroup; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxInputGroupFactory); - - _rxInputGroup = RxInputGroupFactory(); + _rxInputGroup = RxInputGroup; RxInputGroupBase = _rxInputGroup; base.OnInitialized(); diff --git a/RxMudBlazorLight/Menus/MudMenuItemPRx.razor b/RxMudBlazorLight/Menus/MudMenuItemPRx.razor index 0a03644..b1d26cd 100644 --- a/RxMudBlazorLight/Menus/MudMenuItemPRx.razor +++ b/RxMudBlazorLight/Menus/MudMenuItemPRx.razor @@ -5,7 +5,7 @@ @code { [Parameter, EditorRequired] - public required Func> RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public T? Parameter { get; set; } @@ -24,14 +24,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonPRX? _buttonPRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonPRX = ButtonPRX.Create(MBButtonType.DEFAULT, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonPRX = ButtonPRX.Create(MBButtonType.DEFAULT, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); base.OnInitialized(); } @@ -39,12 +35,11 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(_buttonPRX); - ArgumentNullException.ThrowIfNull(_rxCommand); - _rxCommand.PrepareExecution = PrepareExecution; + RxCommand.PrepareExecution = PrepareExecution; _buttonPRX.SetParameters(Parameter); - Disabled = !_rxCommand.CanExecute(Parameter); + Disabled = !RxCommand.CanExecute(Parameter); OnClick = _buttonPRX.OnClick; OnTouch = _buttonPRX.OnTouch; base.OnParametersSet(); diff --git a/RxMudBlazorLight/Menus/MudMenuItemRx.razor b/RxMudBlazorLight/Menus/MudMenuItemRx.razor index 6bbf1c1..4a6610b 100644 --- a/RxMudBlazorLight/Menus/MudMenuItemRx.razor +++ b/RxMudBlazorLight/Menus/MudMenuItemRx.razor @@ -4,7 +4,7 @@ @code { [Parameter, EditorRequired] - public required Func RxCommandFactory { get; init; } + public required ICommand RxCommand { get; init; } [Parameter] public Func? PrepareExecution { get; set; } @@ -20,14 +20,10 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); private ButtonRX? _buttonRX; - private ICommand? _rxCommand; protected override void OnInitialized() { - ArgumentNullException.ThrowIfNull(RxCommandFactory); - _rxCommand = RxCommandFactory(); - - _buttonRX = ButtonRX.Create(MBButtonType.DEFAULT, _rxCommand, ConfirmExecution, BeforeExecution, AfterExecution); + _buttonRX = ButtonRX.Create(MBButtonType.DEFAULT, RxCommand, ConfirmExecution, BeforeExecution, AfterExecution); OnClick = _buttonRX.OnClick; OnTouch = _buttonRX.OnTouch; base.OnInitialized(); @@ -35,10 +31,8 @@ protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(_rxCommand); - - _rxCommand.PrepareExecution = PrepareExecution; - Disabled = !_rxCommand.CanExecute(); + RxCommand.PrepareExecution = PrepareExecution; + Disabled = !RxCommand.CanExecute(); base.OnParametersSet(); } } diff --git a/RxMudBlazorLight/RxMudBlazorLight.csproj b/RxMudBlazorLight/RxMudBlazorLight.csproj index a7a30ff..5586c18 100644 --- a/RxMudBlazorLight/RxMudBlazorLight.csproj +++ b/RxMudBlazorLight/RxMudBlazorLight.csproj @@ -20,7 +20,7 @@ Blazor,MudBlazor,Rx,Reactive true ..\Nuget - 0.6.7 + 0.7.9 diff --git a/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor b/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor index ae22a1c..5aeea48 100644 --- a/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor +++ b/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor @@ -3,6 +3,9 @@ @RenderBase() @code { + [Parameter, EditorRequired] + public required IInput RxInput { get; init; } + [Parameter] public Func>? ConfirmExecution { get; set; } @@ -12,17 +15,12 @@ [Parameter] public Action? AfterExecution { get; set; } - [Parameter] - public IInput? RxInput { get; set; } - private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); protected override void OnParametersSet() { - ArgumentNullException.ThrowIfNull(RxInput); - Toggled = RxInput.Value; - ToggledChanged = EventCallback.Factory.Create(this, v => RxInput.SetValue(v)); + ToggledChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); Disabled = !RxInput.CanChange(); base.OnParametersSet(); diff --git a/RxMudBlazorLight/_Imports.razor b/RxMudBlazorLight/_Imports.razor index f02ddd7..1120253 100644 --- a/RxMudBlazorLight/_Imports.razor +++ b/RxMudBlazorLight/_Imports.razor @@ -1,7 +1,8 @@ @using Microsoft.AspNetCore.Components.Web +@using Microsoft.Extensions.DependencyInjection; @using System.Diagnostics.CodeAnalysis @using MudBlazor @using RxBlazorLightCore @using RxMudBlazorLight.Buttons @using RxMudBlazorLight.ButtonBase -@using RxMudBlazorLight.Extensions \ No newline at end of file +@using RxMudBlazorLight.Extensions diff --git a/RxMudBlazorLightSample/Pages/Index.razor b/RxMudBlazorLightSample/Pages/Index.razor index 3a44a14..0bc06b4 100644 --- a/RxMudBlazorLightSample/Pages/Index.razor +++ b/RxMudBlazorLightSample/Pages/Index.razor @@ -7,7 +7,7 @@ You can find documentation and a sample for RxMudBlazorLight here: RxMudBlazorLight You can find documentation and examples for MudBlazor here: www.mudblazor.com -@if (!ServiceInitialized) +@if (!Service.Initialized) { Waiting for TestService! } @@ -15,5 +15,5 @@ @code { [CascadingParameter] - public required bool ServiceInitialized { get; init; } + public required TestService Service { get; init; } } \ No newline at end of file diff --git a/RxMudBlazorLightSample/Program.cs b/RxMudBlazorLightSample/Program.cs index b48f820..3a64e53 100644 --- a/RxMudBlazorLightSample/Program.cs +++ b/RxMudBlazorLightSample/Program.cs @@ -1,9 +1,9 @@ using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using RxMudBlazorLightSample; using MudBlazor.Services; -using RxMudBlazorLightTestBase.Service; using RxBlazorLightCore; +using RxMudBlazorLightSample; +using RxMudBlazorLightTestBase.Service; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); @@ -11,8 +11,8 @@ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddMudServices(); + builder.Services.AddRxBLService(sp => new TestService(sp)); -builder.Services.AddSingleton(); builder.Services.AddRxBLService(); await builder.Build().RunAsync(); diff --git a/RxMudBlazorLightSample/Shared/MainLayout.razor b/RxMudBlazorLightSample/Shared/MainLayout.razor index fced78d..89c81eb 100644 --- a/RxMudBlazorLightSample/Shared/MainLayout.razor +++ b/RxMudBlazorLightSample/Shared/MainLayout.razor @@ -3,9 +3,10 @@ + - + @@ -22,7 +23,7 @@ @Body - + @code { diff --git a/RxMudBlazorLightSample/_Imports.razor b/RxMudBlazorLightSample/_Imports.razor index 82e941b..1b558c3 100644 --- a/RxMudBlazorLightSample/_Imports.razor +++ b/RxMudBlazorLightSample/_Imports.razor @@ -13,4 +13,3 @@ @using RxMudBlazorLightTestBase.Components @using RxMudBlazorLightTestBase.Service @using RxBlazorLightCore -@using RxBlazorLightCore.Component \ No newline at end of file diff --git a/RxMudBlazorLightTestBase/Components/ButtonTest.razor b/RxMudBlazorLightTestBase/Components/ButtonTest.razor index bd74775..5397682 100644 --- a/RxMudBlazorLightTestBase/Components/ButtonTest.razor +++ b/RxMudBlazorLightTestBase/Components/ButtonTest.razor @@ -1,70 +1,74 @@ -Counter +ButtonTest Counter - - Current count: @Service.Count - - - Service.Increment) ConfirmExecution=@ConfirmIncrement>Increment - Service.Add)>Add 5 - - Service.IncrementAsync)> - IncrementAsync - - - @Service.AddAsync) PrepareExecutionAsync=@DoPrepareAddAsync CancelColor=Color.Error CancelText="Cancel Add"> - AddAsync 2 - - - - - - Service.Increment) ConfirmExecution=@ConfirmIncrement>Increment - Service.Add)>Add 5 - CmdDialogClick()) OnTouch=@(() => CmdDialogClick())>IncrementAsync - CmdDialogClick(2)) OnTouch=@(() => CmdDialogClick(2))>AddAsync 2 - - - - - Service.Increment) Label="Increment" /> - Service.Add) Label="Add 2" /> - Service.IncrementAsync) Label="IncrementAsync" /> - Service.AddAsync) PrepareExecutionAsync=@DoPrepareAddAsync Label="AddAsync 2" /> - Service.AddAsync) PrepareExecutionAsync=@DoPrepareAddAsync Label="AddAsync 5" /> - - - - Service.Increment) /> - Service.Add) /> - Service.IncrementAsync) /> - Service.AddAsync) PrepareExecutionAsync=@DoPrepareAddAsync /> - Service.AddAsync) PrepareExecutionAsync=@DoPrepareAddAsync /> - - - - - Service.AddRemoveAsync) /> - - - - CmdDialogClick())>Increment AsyncDialog - CmdDialogClick(10))>Add AsyncDialog 10 - - - - @if (Service.Exceptions.Any()) + @Service.State.Value.State + + + + + + + Current count: @Service.Count + + + Increment + Add 5 + + + IncrementAsync + + + + AddAsync 2 + + + + + + Increment + Add 5 + CmdDialogClick()) OnTouch=@(() => CmdDialogClick())>IncrementAsync + CmdDialogClick(2)) OnTouch=@(() => CmdDialogClick(2))>AddAsync 2 + + + + + + + + + + + + + + + + + + + + + + CmdDialogClick())>Increment AsyncDialog + CmdDialogClick(10))>Add AsyncDialog 10 + Service.ChangeState("TEST1"))>Change State to Test1 + Service.ChangeState("TEST2"))>Change State to Test2 + + + + @if (Service.Exceptions.Any()) { @GetExceptions() - Service.ResetExceptions())>Reset Exceptions - + Service.ResetExceptions())>Reset Exceptions + } - Service.Exception) Label="New Exception" /> + @@ -108,7 +112,7 @@ var parameters = new DialogParameters { - ["Message"] = $"Add {parameter} to counter?", + ["Message"] = $"Add {cmd.Parameter} * 2 to counter?", ["ConfirmButton"] = "Add" }; diff --git a/RxMudBlazorLightTestBase/Components/IconButtons.razor b/RxMudBlazorLightTestBase/Components/IconButtons.razor new file mode 100644 index 0000000..aff490b --- /dev/null +++ b/RxMudBlazorLightTestBase/Components/IconButtons.razor @@ -0,0 +1,15 @@ + + + + + + + + +@code { + [CascadingParameter] + public required TestService Service { get; init; } + + [CascadingParameter] + public required TestService.SubScope Scope { get; init; } +} diff --git a/RxMudBlazorLightTestBase/Components/InputTest.razor b/RxMudBlazorLightTestBase/Components/InputTest.razor index de5d687..a254ffc 100644 --- a/RxMudBlazorLightTestBase/Components/InputTest.razor +++ b/RxMudBlazorLightTestBase/Components/InputTest.razor @@ -1,51 +1,54 @@ @implements IDisposable +InputTest @($"InputTest {Service.TextValue.Value} / {Service.GetRadio().Value} / {Service.RatingValue.Value}") - + + + + Current count: @Service.Count - - - - Size.Large) PlacementCallback=@(_ => Placement.Start) /> - - - Service.GetRadio()) Variant="Variant.Outlined"> - - Red - - - Green - - - Blue - - - - - - - - - - - - - - - CanIncrementCheck is @(Service.CanIncrementCheck.Value ? "On" : "Off") - - IncrementValue - Service.AddIncrementValue)>Add Direct - Service.Add)>Add - - @($"Simple CMD executions {_simpleExecutions}") - Service.Simple)>Simple CMD - - - - + + + Size.Large) PlacementCallback=@(_ => Placement.Start) /> + + + + + Red + + + Green + + + Blue + + + + + + + + + + + + + + + CanIncrementCheck is @(Service.CanIncrementCheck.Value ? "On" : "Off") + + IncrementValue + Add Direct + Add + + @($"Simple CMD executions {_simpleExecutions}") + Simple CMD + + + + @code { [CascadingParameter] @@ -90,7 +93,7 @@ { ColorEnum.RED => Color.Error, ColorEnum.GREEN => Color.Success, - _ => Color.Default + _ => Color.Primary }; } diff --git a/RxMudBlazorLightTestBase/Components/TestPlayground.razor b/RxMudBlazorLightTestBase/Components/TestPlayground.razor index 6d6291d..7e5e39b 100644 --- a/RxMudBlazorLightTestBase/Components/TestPlayground.razor +++ b/RxMudBlazorLightTestBase/Components/TestPlayground.razor @@ -1,31 +1,28 @@ @implements IDisposable +TestPlayground @($"InputTest {Service.TextValue.Value} / {Service.GetRadio().Value} / {Service.RatingValue.Value}") - + + + + Current count: @Service.Count - - Service.Increment)>Increment - Service.Add)>Add + + Increment + Add @($"Equals executions {_equalsExecutions}") - Service.EqualsTest)>EqualsTest + EqualsTest @($"Equals async executions {_equalsAsyncExecutions}") - Service.EqualsTestAsync)>EqualsTest + EqualsTest _showNestedTimer = !_showNestedTimer)>Throw nested RxServiceException - @if (_showNestedTimer) - { - - - - } - @if (TimerService.Exceptions.Any()) + @if (Service.Exceptions.Any()) { - _showNestedTimer = false; @GetExceptions() - TimerService.ResetExceptions())>Reset Exceptions + Service.ResetExceptions())>Reset Exceptions } @@ -35,9 +32,6 @@ [CascadingParameter] public required TestService Service { get; init; } - [CascadingParameter] - public required TimerService TimerService { get; init; } - private long _equalsExecutions = 0; private long _equalsAsyncExecutions = 0; @@ -84,6 +78,6 @@ private string GetExceptions() { - return TimerService.Exceptions.Aggregate("", (p, n) => p + n.Message + ", ").TrimEnd(new[] { ' ', ',' }); + return Service.Exceptions.Aggregate("", (p, n) => p + n.Message + ", ").TrimEnd(new[] { ' ', ',' }); } } \ No newline at end of file diff --git a/RxMudBlazorLightTestBase/Components/TimerComponent.razor b/RxMudBlazorLightTestBase/Components/TimerComponent.razor index 1376117..7f23fb5 100644 --- a/RxMudBlazorLightTestBase/Components/TimerComponent.razor +++ b/RxMudBlazorLightTestBase/Components/TimerComponent.razor @@ -1,3 +1,14 @@ -@inherits RxBLServiceContext + + + Current seconds in @Name: @Scope.ComponentTimer.Value + -Current seconds in component: @Service.ComponentTimer \ No newline at end of file +@code +{ + [CascadingParameter] + public required TimerService.TimerScope Scope { get; init; } + + [Parameter, EditorRequired] + public required string Name { get; init; } +} \ No newline at end of file diff --git a/RxMudBlazorLightTestBase/Service/TestService.Commands.cs b/RxMudBlazorLightTestBase/Service/TestService.Commands.cs index 09d4bd3..30eda84 100644 --- a/RxMudBlazorLightTestBase/Service/TestService.Commands.cs +++ b/RxMudBlazorLightTestBase/Service/TestService.Commands.cs @@ -42,14 +42,14 @@ public override bool CanExecute(int parameter) } public class ExceptionCMD(TestService testService) : CommandService(testService) - { + { protected override void DoExecute() - { + { throw new InvalidOperationException("Command test exception!"); - } - } + } + } - public class IncrementCMD(TestService testService) : CommandService(testService) + public class IncrementCMD(TestService testService) : CommandService(testService) { protected override void DoExecute() { diff --git a/RxMudBlazorLightTestBase/Service/TestService.Input.cs b/RxMudBlazorLightTestBase/Service/TestService.Input.cs index 344be80..58806a1 100644 --- a/RxMudBlazorLightTestBase/Service/TestService.Input.cs +++ b/RxMudBlazorLightTestBase/Service/TestService.Input.cs @@ -6,7 +6,7 @@ public sealed partial class TestService { public class IncrementValueIP(TestService service, int value) : Input(service, value) { - protected override void OnValueChanging(int oldValue, int newValue) + protected override void OnValueChanged(int oldValue, int newValue) { Service.Count = newValue; } @@ -33,44 +33,14 @@ public override bool CanChange() } } - public class PizzaIPGAsync(TestService service) : InputGroupAsync(service, null) - { - private static readonly Pizza[] _pizzas = - [ - new("Cardinale"), new("Diavolo"), new("Margarita"), new("Spinaci") - ]; - - private bool _initialized = false; - - public override Pizza[] GetItems() - { - - return _pizzas; - } - - public override bool CanChange() - { - return _initialized; - } - - public override void Initialize() - { - SetInitialValue(_pizzas[3]); - } - - public override async Task InitializeAsync() - { - await Task.Delay(2000); - await SetInitialValueAsync(_pizzas[1]); - _initialized = true; - } - } - public class PizzaIPG(TestService service, Pizza value) : InputGroup(service, value) { public static readonly Pizza[] Pizzas = [ - new("Cardinale"), new("Diavolo"), new("Margarita"), new("Spinaci") + new("Cardinale"), + new("Diavolo"), + new("Margarita"), + new("Spinaci") ]; public override Pizza[] GetItems() @@ -80,29 +50,20 @@ public override Pizza[] GetItems() } } - public class ColorIPGP(TestService service) : InputGroupP(service, _colors[0]) + public class ColorIPGP(TestService service) : InputGroup(service, _colors[0]) { private static readonly TestColor[] _colors = [ - new(ColorEnum.RED), new(ColorEnum.GREEN), new(ColorEnum.BLUE) + new(ColorEnum.RED), + new(ColorEnum.GREEN), + new(ColorEnum.BLUE) ]; - private bool _initialized = false; - public override TestColor[] GetItems() { return _colors; } - public override void Initialize() - { - if (!_initialized) - { - _initialized = true; - SetInitialValue(new TestColor(Parameter)); - } - } - public override bool IsItemDisabled(int index) { return index == 1 && Service.CanIncrementCheck.Value; diff --git a/RxMudBlazorLightTestBase/Service/TestService.cs b/RxMudBlazorLightTestBase/Service/TestService.cs index 8ecd74a..b436002 100644 --- a/RxMudBlazorLightTestBase/Service/TestService.cs +++ b/RxMudBlazorLightTestBase/Service/TestService.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.DependencyInjection; -using RxBlazorLightCore; +using RxBlazorLightCore; namespace RxMudBlazorLightTestBase.Service { @@ -40,19 +39,30 @@ public enum ColorEnum BLUE } - public sealed partial class TestService : RxBLServiceBase + public record StateInfo(string State); + + public sealed partial class TestService : RxBLService { + public IInput State { get; } + public int Count { get; private set; } public ICommand Simple { get; } - public ICommand Exception { get; } + public ICommand Exception { get; } + + public partial class SubScope(TestService service) : IRxBLScope + { + public ICommand Increment = new IncrementCMD(service); + + public ICommandAsync AddAsync = new AddAsyncCMD(service); + } + + public ICommand Increment { get; } + public ICommandAsync AddAsync { get; } public ICommand EqualsTest { get; } public ICommandAsync EqualsTestAsync { get; } - - public ICommand Increment => new IncrementCMD(this); public ICommand Add { get; } public ICommandAsync IncrementAsync { get; } - public ICommandAsync AddAsync => new AddAsyncCMD(this); public ICommandAsync AddAsyncForm { get; } public ICommandAsync AddRemoveAsync { get; } public IInput AddMode { get; } @@ -61,26 +71,29 @@ public sealed partial class TestService : RxBLServiceBase public IInput IncrementValue { get; } public IInput CanIncrementCheck { get; } public IInput TextValue { get; } - public IInput RatingValue { get; } - private readonly IInputGroupAsync _pizzaIPGAsync; - private readonly IInputGroup _pizzaIPG; - private readonly IInputGroup _radioTestExtended; + private readonly IInputGroup _pizzaInput1; + private readonly IInputGroup _pizzaInput2; + + private readonly IInputGroup _radioTestExtended; private bool _canIncrement = false; - public TestService(IServiceProvider serviceProvider) + public TestService(IServiceProvider _) { Console.WriteLine("TestService Create"); - var ts = serviceProvider.GetRequiredService(); - Count = (int)ts.ComponentTimer; + State = CreateInput(this, new StateInfo("None")); + + Increment = new IncrementCMD(this); + AddAsync = new AddAsyncCMD(this); + Simple = new SimpleCMD(); EqualsTest = new EqualsTestCmd(); EqualsTestAsync = new EqualsTestAsyncCmd(); Exception = new ExceptionCMD(this); - Add = new AddCMD(this); + Add = new AddCMD(this); IncrementAsync = new IncrementAsyncCMD(this); AddAsyncForm = new AddAsyncCMDForm(this); AddRemoveAsync = new AddRemoveAsyncCMDForm(this); @@ -92,17 +105,22 @@ public TestService(IServiceProvider serviceProvider) RatingValue = new RatingValueIP(this, 0); AddIncrementValue = new AddIncrementValueCMD(this); - _pizzaIPGAsync = new PizzaIPGAsync(this); - _pizzaIPG = new PizzaIPG(this, PizzaIPG.Pizzas[0]); + _pizzaInput1 = new PizzaIPG(this, PizzaIPG.Pizzas[0]); + _pizzaInput2 = new PizzaIPG(this, PizzaIPG.Pizzas[2]); + _radioTestExtended = new ColorIPGP(this); } - protected override async ValueTask InitializeContext() + public override IRxBLScope CreateScope() + { + return new SubScope(this); + } + + protected override async ValueTask InitializeContextAsync() { Console.WriteLine("TestService OnContextInitialized"); await Task.Delay(3000); _canIncrement = true; - StateHasChanged(); } protected override void DisposeContext() @@ -111,17 +129,22 @@ protected override void DisposeContext() Console.WriteLine("TestService OnContextDisposed"); } - public IInputGroup GetPizzaInput() + public void ChangeState(string state) + { + State.Value = State.Value with { State = state }; + } + + public IInputGroup GetPizzas1() { - return _pizzaIPG; + return _pizzaInput1; } - public IInputGroupAsync GetPizzaInputAsync() + public IInputGroup GetPizzas2() { - return _pizzaIPGAsync; + return _pizzaInput2; } - public IInputGroup GetRadio() + public IInputGroup GetRadio() { return _radioTestExtended; } diff --git a/RxMudBlazorLightTestBase/Service/TimerService.cs b/RxMudBlazorLightTestBase/Service/TimerService.cs new file mode 100644 index 0000000..c8d8a0b --- /dev/null +++ b/RxMudBlazorLightTestBase/Service/TimerService.cs @@ -0,0 +1,55 @@ +using RxBlazorLightCore; +using System.Reactive.Linq; + +namespace RxMudBlazorLightTestBase.Service +{ + public class TimerService : RxBLService + { + public enum State + { + STARTED, + OVER20 + } + + public override IRxBLScope CreateScope() + { + return new TimerScope(this); + } + + public sealed partial class TimerScope(TimerService service) : IRxBLScope + { + public IInput ComponentTimer { get; } = CreateInput(service, 0L); + public IInput Suspended { get; } = CreateInput(service, false); + + public IInput TimerState { get; } = CreateInput(service, State.STARTED); + + private IDisposable? _timerDisposable; + + public void EnterScope() + { + _timerDisposable = Observable.Interval(TimeSpan.FromSeconds(1)) + .StartWith(0) + .Subscribe(_ => + { + if (!Suspended.Value) + { + ComponentTimer.Value++; + + if (ComponentTimer.Value > 20 && TimerState.Value is State.STARTED) + { + TimerState.Value = State.OVER20; + } + } + }); + + Console.WriteLine("TimerScope Entered"); + } + + public void LeaveScope() + { + _timerDisposable?.Dispose(); + Console.WriteLine("TimerScope Left"); + } + } + } +} diff --git a/RxMudBlazorLightTestBase/Service/TimerServices.cs b/RxMudBlazorLightTestBase/Service/TimerServices.cs deleted file mode 100644 index 299f367..0000000 --- a/RxMudBlazorLightTestBase/Service/TimerServices.cs +++ /dev/null @@ -1,40 +0,0 @@ -using RxBlazorLightCore; -using System.Reactive.Linq; - -namespace RxMudBlazorLightTestBase.Service -{ - public sealed partial class TimerService : RxBLServiceBase - { - public long ComponentTimer { get; private set; } - - private IDisposable? _componentTimerDisposable; - - public TimerService() - { - ComponentTimer = 0; - Console.WriteLine("TimerService Create"); - } - - protected override ValueTask InitializeContext() - { - Console.WriteLine("TimerService OnContextInitialized"); - - _componentTimerDisposable = Observable.Interval(TimeSpan.FromSeconds(1)) - .StartWith(0) - .Subscribe(s => - { - ComponentTimer = s; - StateHasChanged(); - }); - - return ValueTask.CompletedTask; - } - - protected override void DisposeContext() - { - _componentTimerDisposable?.Dispose(); - _componentTimerDisposable = null; - Console.WriteLine("TimerService OnContextDisposed"); - } - } -} diff --git a/RxMudBlazorLightTestBase/_Imports.razor b/RxMudBlazorLightTestBase/_Imports.razor index 9043757..1d9c949 100644 --- a/RxMudBlazorLightTestBase/_Imports.razor +++ b/RxMudBlazorLightTestBase/_Imports.razor @@ -7,7 +7,6 @@ @using RxMudBlazorLightTestBase.Dialogs @using RxMudBlazorLightTestBase.Service @using RxBlazorLightCore -@using RxBlazorLightCore.Component @using RxMudBlazorLight.Buttons @using RxMudBlazorLight.Dialogs @using RxMudBlazorLight.FabButtons diff --git a/RxMudBlazorLightTests/Context/TestContextBase.cs b/RxMudBlazorLightTests/Context/TestContextBase.cs index cc27af8..40c7b1a 100644 --- a/RxMudBlazorLightTests/Context/TestContextBase.cs +++ b/RxMudBlazorLightTests/Context/TestContextBase.cs @@ -1,18 +1,19 @@  using MudBlazor.Services; -using RxMudBlazorLightTestBase.Service; using RxBlazorLightCore; +using RxMudBlazorLightTestBase.Service; namespace RxMudBlazorLightTests.Context { public class TestContextBase : TestContext { - public TestContextBase() + public TestContextBase() { Services.AddMudServices(); + Services.AddRxBLService(sp => new TestService(sp)); - Services.AddSingleton(); Services.AddRxBLService(); + JSInterop.Mode = JSRuntimeMode.Loose; } } diff --git a/RxMudBlazorLightTests/Extensions/TestExtensions.cs b/RxMudBlazorLightTests/Extensions/TestExtensions.cs index 3f6a5b5..2f468cd 100644 --- a/RxMudBlazorLightTests/Extensions/TestExtensions.cs +++ b/RxMudBlazorLightTests/Extensions/TestExtensions.cs @@ -4,47 +4,47 @@ namespace RxMudBlazorLightTests.Extensions { - internal static class TestExtensions - { - private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(5); + internal static class TestExtensions + { + private static readonly TimeSpan _defaultTimeout = TimeSpan.FromSeconds(5); - public static async Task ClickAsync(this IRenderedFragment fragment, string id) - { - await fragment.FindID(id).ClickAsync(new MouseEventArgs()); - } + public static async Task ClickAsync(this IRenderedFragment fragment, string id) + { + await fragment.FindID(id).ClickAsync(new MouseEventArgs()); + } public static void Click(this IRenderedFragment fragment, string id) { - fragment.FindID(id).Click(); + fragment.FindID(id).Click(); } public static void VerifyTextContent(this IRenderedFragment fragment, string id, string text) - { - fragment.WaitForState(() => fragment.FindID(id).TextContent.Equals(text, StringComparison.InvariantCultureIgnoreCase), _defaultTimeout); - } - - public static void VerifyMudChecked(this IRenderedFragment fragment, IElement? element) - { - fragment.WaitForState(() => element is not null && !element.HasAttribute("mud-checked"), _defaultTimeout); - } - - public static void VerifyEnabled(this IRenderedFragment fragment, string id) - { - fragment.WaitForState(() => !fragment.FindID(id).HasAttribute("disabled"), _defaultTimeout); - } - - public static IElement FindID(this IRenderedFragment fragment, string id) - { - return fragment.Find($"#{id.ToLowerInvariant()}"); - } - - public static IElement? FindMudRadioButton(this IRenderedFragment fragment, string radioId, string buttonText) - { - var buttons = fragment.FindID(radioId).Children - .SelectMany(c => c.Children) - .Where(c => c.ClassName is not null && c.ClassName.Contains("mud-button-root")); - - return buttons.Where(c => c.ParentElement is not null && c.ParentElement.TextContent.Contains(buttonText, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); - } - } + { + fragment.WaitForState(() => fragment.FindID(id).TextContent.Equals(text, StringComparison.InvariantCultureIgnoreCase), _defaultTimeout); + } + + public static void VerifyMudChecked(this IRenderedFragment fragment, IElement? element) + { + fragment.WaitForState(() => element is not null && !element.HasAttribute("mud-checked"), _defaultTimeout); + } + + public static void VerifyEnabled(this IRenderedFragment fragment, string id) + { + fragment.WaitForState(() => !fragment.FindID(id).HasAttribute("disabled"), _defaultTimeout); + } + + public static IElement FindID(this IRenderedFragment fragment, string id) + { + return fragment.Find($"#{id.ToLowerInvariant()}"); + } + + public static IElement? FindMudRadioButton(this IRenderedFragment fragment, string radioId, string buttonText) + { + var buttons = fragment.FindID(radioId).Children + .SelectMany(c => c.Children) + .Where(c => c.ClassName is not null && c.ClassName.Contains("mud-button-root")); + + return buttons.Where(c => c.ParentElement is not null && c.ParentElement.TextContent.Contains(buttonText, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); + } + } } diff --git a/RxMudBlazorLightTests/RxMudBlazorLightTests.csproj b/RxMudBlazorLightTests/RxMudBlazorLightTests.csproj index e1462a6..4705ebe 100644 --- a/RxMudBlazorLightTests/RxMudBlazorLightTests.csproj +++ b/RxMudBlazorLightTests/RxMudBlazorLightTests.csproj @@ -35,6 +35,4 @@ - - diff --git a/RxMudBlazorLightTests/TestComponents/TestPlaygroundComponent.razor b/RxMudBlazorLightTests/TestComponents/TestPlaygroundComponent.razor index 0156a47..a2831ea 100644 --- a/RxMudBlazorLightTests/TestComponents/TestPlaygroundComponent.razor +++ b/RxMudBlazorLightTests/TestComponents/TestPlaygroundComponent.razor @@ -1,5 +1,6 @@  - - - + + + + diff --git a/RxMudBlazorLightTests/_Imports.razor b/RxMudBlazorLightTests/_Imports.razor index 64b2b26..2e88885 100644 --- a/RxMudBlazorLightTests/_Imports.razor +++ b/RxMudBlazorLightTests/_Imports.razor @@ -8,7 +8,6 @@ @using RxMudBlazorLightTestBase.Components @using RxMudBlazorLightTestBase.Service @using RxBlazorLightCore -@using RxBlazorLightCore.Component @using RxMudBlazorLightTests.Context @using RxMudBlazorLightTests.Extensions @using RxMudBlazorLightTests.TestComponents \ No newline at end of file From 43ec6342d16980d202c2516cb85f0ab179b8506e Mon Sep 17 00:00:00 2001 From: Bernhard Straub Date: Fri, 19 Jan 2024 22:17:48 +0100 Subject: [PATCH 3/3] RX Input Revise usage of input --- RxBlazorLightCore/Core/CommandExtensions.cs | 79 ----------- RxBlazorLightCore/Core/Commands.cs | 22 +-- RxBlazorLightCore/Core/Input.cs | 130 +++++++++++++----- RxBlazorLightCore/Core/Interfaces.cs | 28 +++- RxBlazorLightCore/Core/RxExtensions.cs | 51 +++++++ RxBlazorLightCore/Core/Service.cs | 18 +-- .../Dialogs/DialogAsyncPRx.razor.cs | 4 +- .../Dialogs/DialogAsyncRx.razor.cs | 4 +- .../Inputs/MudAutocompleteRx.razor | 13 +- RxMudBlazorLight/Inputs/MudCheckBoxRx.razor | 18 +-- .../Inputs/MudNumericFieldRx.razor | 18 ++- RxMudBlazorLight/Inputs/MudRatingRx.razor | 8 +- RxMudBlazorLight/Inputs/MudSliderRx.razor | 14 +- RxMudBlazorLight/Inputs/MudSwitchRx.razor | 17 ++- RxMudBlazorLight/Inputs/MudTextFieldRx.razor | 9 +- .../Inputs/Radio/MudRadioGroupBaseRx.cs | 9 +- .../Inputs/Radio/MudRadioGroupRx.razor | 5 +- .../Inputs/Select/MudSelectBaseRx.cs | 13 +- .../Inputs/Select/MudSelectRx.razor | 5 +- .../MudToggleIconButtonRx.razor | 2 +- .../Components/ButtonTest.razor | 122 ++++++++-------- .../Components/InputTest.razor | 25 +++- .../Components/TestPlayground.razor | 10 +- .../Service/TestService.Input.cs | 11 +- .../Service/TestService.cs | 18 ++- 25 files changed, 372 insertions(+), 281 deletions(-) delete mode 100644 RxBlazorLightCore/Core/CommandExtensions.cs create mode 100644 RxBlazorLightCore/Core/RxExtensions.cs diff --git a/RxBlazorLightCore/Core/CommandExtensions.cs b/RxBlazorLightCore/Core/CommandExtensions.cs deleted file mode 100644 index dc27a0c..0000000 --- a/RxBlazorLightCore/Core/CommandExtensions.cs +++ /dev/null @@ -1,79 +0,0 @@ - -using System.Reactive; -using System.Reactive.Linq; - -namespace RxBlazorLightCore -{ - public static class CommandExtensions - { - public static bool Preparing(this ICommandBase commandBase) - { - return commandBase.State is CommandState.PREPARING; - } - - public static IObservable PreparingObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.PREPARING).Select(_ => Unit.Default); - } - - public static bool Executing(this ICommandBase commandBase) - { - return commandBase.State is CommandState.EXECUTING; - } - - public static IObservable ExecutingObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.EXECUTING).Select(_ => Unit.Default); - } - - public static bool Executed(this ICommandBase commandBase) - { - return commandBase.State is CommandState.EXECUTED; - } - - public static IObservable ExecutedObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.EXECUTED).Select(_ => Unit.Default); - } - - public static bool NotExecuted(this ICommandBase commandBase) - { - return commandBase.State is CommandState.NOT_EXECUTED; - } - - public static IObservable NotExecutedObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.NOT_EXECUTED).Select(_ => Unit.Default); - } - - public static bool Canceled(this ICommandBase commandBase) - { - return commandBase.State is CommandState.CANCELED; - } - - public static IObservable CanceledObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.CANCELED).Select(_ => Unit.Default); - } - - public static bool Exception(this ICommandBase commandBase) - { - return commandBase.State is CommandState.EXCEPTION; - } - - public static IObservable ExceptionObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.EXCEPTION).Select(_ => Unit.Default); - } - - public static bool Running(this ICommandBase commandBase) - { - return commandBase.State is CommandState.PREPARING || commandBase.State is CommandState.EXECUTING; - } - - public static IObservable RunningObservable(this ICommandBase commandBase) - { - return commandBase.Where(cs => cs is CommandState.PREPARING || cs is CommandState.EXECUTING).Select(_ => Unit.Default); - } - } -} diff --git a/RxBlazorLightCore/Core/Commands.cs b/RxBlazorLightCore/Core/Commands.cs index 64a66f4..47705b8 100644 --- a/RxBlazorLightCore/Core/Commands.cs +++ b/RxBlazorLightCore/Core/Commands.cs @@ -1,17 +1,17 @@ - +using System.Reactive; using System.Reactive.Linq; using System.Reactive.Subjects; namespace RxBlazorLightCore { - public class CommandBase : IObservable + public class CommandBase { public CommandState State { get; private set; } = CommandState.NONE; public Exception? LastException { get; protected set; } - private readonly Subject _changedSubject; - private readonly IObservable _changedObservable; + private readonly Subject _changedSubject; + private readonly IObservable _changedObservable; protected CommandBase() { @@ -24,15 +24,15 @@ public virtual bool PrepareModal() return true; } - public IDisposable Subscribe(IObserver observer) + public IDisposable Subscribe(Action stateHasChanged) { - return _changedObservable.Subscribe(observer); + return _changedObservable.Subscribe(_ => stateHasChanged()); } protected void Changed(CommandState state) { State = state; - _changedSubject.OnNext(state); + _changedSubject.OnNext(Unit.Default); } } @@ -154,7 +154,7 @@ public abstract class CommandService : Command, IDisposable where S : RxBLSer protected CommandService(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); + _serviceDisposable = Subscribe(() => Service.StateHasChanged(State is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -182,7 +182,7 @@ public abstract class CommandService : Command, IDisposable where S : R protected CommandService(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); + _serviceDisposable = Subscribe(() => Service.StateHasChanged(State is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -409,7 +409,7 @@ public abstract class CommandServiceAsync : CommandAsync, IDisposable where S protected CommandServiceAsync(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); + _serviceDisposable = Subscribe(() => Service.StateHasChanged(State is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) @@ -437,7 +437,7 @@ public abstract class CommandServiceAsync : CommandAsync, IDisposable w protected CommandServiceAsync(S service) { Service = service; - _serviceDisposable = this.Subscribe(cs => Service.StateHasChanged(cs is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); + _serviceDisposable = Subscribe(() => Service.StateHasChanged(State is CommandState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.COMMAND, LastException)); } protected virtual void Dispose(bool disposing) diff --git a/RxBlazorLightCore/Core/Input.cs b/RxBlazorLightCore/Core/Input.cs index fc0bb20..b4ac453 100644 --- a/RxBlazorLightCore/Core/Input.cs +++ b/RxBlazorLightCore/Core/Input.cs @@ -3,9 +3,9 @@ namespace RxBlazorLightCore { - public class InputBase : IObservable + public class InputBase : IInput { - public T Value + public T? Value { get { @@ -17,51 +17,103 @@ public T Value } } - private readonly Subject _changedSubject; - private readonly IObservable _changedObservable; - private T _value; + public InputState State { get; private set; } = InputState.NONE; - protected InputBase(T value) + public Exception? LastException { get; private set; } + + private readonly Subject _changedSubject; + private readonly IObservable _changedObservable; + private T? _value; + private CancellationTokenSource _cancellationTokenSource; + + protected InputBase(T? value) { _value = value; _changedSubject = new(); _changedObservable = _changedSubject.Publish().RefCount(); + _cancellationTokenSource = new(); + } - _changedObservable - .Select(async newValue => - { - OnValueChanged(_value, newValue); - await OnValueChangedAsync(_value, newValue); - _value = newValue; - return _value; - }) - .Subscribe(); + public bool HasValue() + { + return Value is not null; } - protected virtual void OnValueChanged(T oldValue, T newValue) { } - protected virtual ValueTask OnValueChangedAsync(T oldValue, T newValue) + public virtual bool CanChange() { - return ValueTask.CompletedTask; + return true; } - private void SetValue(T value) + public void Cancel() { - if (CanChange()) + _cancellationTokenSource.Cancel(); + } + + protected void ResetCancel() + { + if (!_cancellationTokenSource.TryReset()) { - _changedSubject.OnNext(value); + _cancellationTokenSource = new(); } } - public virtual bool CanChange() + protected virtual void OnValueChanged(T? oldValue, T newValue) { } + protected virtual ValueTask OnValueChangedAsync(T? oldValue, T newValue, CancellationToken cancellationToken) { - return true; + return ValueTask.CompletedTask; } - public IDisposable Subscribe(IObserver observer) + public IDisposable Subscribe(Action stateHasChanged) { return _changedObservable - .StartWith(_value) - .Subscribe(observer); + .StartWith(_value) + .Select(async newValue => + { + if (newValue is not null && !newValue.Equals(_value)) + { + LastException = null; + ResetCancel(); + State = InputState.CHANGING; + stateHasChanged(); + var _canceledOrError = false; + + try + { + OnValueChanged(_value, newValue); + await OnValueChangedAsync(_value, newValue, _cancellationTokenSource.Token); + } + catch (Exception ex) + { + if (ex.GetType() == typeof(TaskCanceledException)) + { + State = InputState.CANCELED; + } + else + { + LastException = ex; + State = InputState.EXCEPTION; + } + + _canceledOrError = true; + } + + if (!_canceledOrError) + { + _value = newValue; + State = InputState.CHANGED; + } + stateHasChanged(); + } + }) + .Subscribe(); + } + + private void SetValue(T? value) + { + if (CanChange()) + { + _changedSubject.OnNext(value); + } } } @@ -70,10 +122,10 @@ public class InputBase : InputBase, IDisposable where S : RxBLService protected S Service { get; } private IDisposable? _serviceDisposable; - protected InputBase(S service, T value) : base(value) + protected InputBase(S service, T? value) : base(value) { Service = service; - _serviceDisposable = this.Subscribe(_ => Service.StateHasChanged(ServiceStateChanged.INPUT, null)); + _serviceDisposable = Subscribe(() => Service.StateHasChanged(State is InputState.EXCEPTION ? ServiceStateChanged.EXCEPTION : ServiceStateChanged.INPUT, LastException)); } protected virtual void Dispose(bool disposing) @@ -92,26 +144,34 @@ public void Dispose() } } - public class Input(T value) : InputBase(value), IInput + public class Input(T? value) : InputBase(value) { } - public class Input : InputBase, IInput where S : RxBLService + public class Input : InputBase where S : RxBLService { - protected Input(S service, T value) : base(service, value) + private readonly Func? _canChange; + + protected Input(S service, T? value, Func? canChange = null) : base(service, value) + { + _canChange = canChange; + } + + public override bool CanChange() { + return _canChange is null ? base.CanChange() : _canChange(); } - public static IInput Create(S service, T value) + public static IInput Create(S service, T? value, Func? canChange = null) { - return new Input(service, value); + return new Input(service, value, canChange); } } public abstract class InputGroup : Input, IInputGroup { - protected InputGroup(T value) : base(value) + protected InputGroup(T? value) : base(value) { } @@ -126,7 +186,7 @@ public virtual bool IsItemDisabled(int index) public abstract class InputGroup : Input, IInputGroup where S : RxBLService { - protected InputGroup(S service, T value) : base(service, value) + protected InputGroup(S service, T? value) : base(service, value) { } diff --git a/RxBlazorLightCore/Core/Interfaces.cs b/RxBlazorLightCore/Core/Interfaces.cs index 773c765..98a986d 100644 --- a/RxBlazorLightCore/Core/Interfaces.cs +++ b/RxBlazorLightCore/Core/Interfaces.cs @@ -1,4 +1,6 @@ - +using System.Diagnostics.CodeAnalysis; +using System.Reactive; + namespace RxBlazorLightCore { internal enum ServiceStateChanged @@ -27,10 +29,27 @@ public interface IRxBLService public IDisposable Subscribe(Action stateHasChanged, double sampleMS); } - public interface IInput : IObservable + public enum InputState { - public T Value { get; set; } + NONE, + CHANGING, + CHANGED, + CANCELED, + EXCEPTION + } + + public interface IInput + { + public InputState State { get; } + public Exception? LastException { get; } + public T? Value { get; set; } + + [MemberNotNullWhen(true, nameof(Value))] + public bool HasValue(); public bool CanChange(); + public void Cancel(); + + public IDisposable Subscribe(Action stateHasChanged); } public interface IInputGroup : IInput @@ -50,11 +69,12 @@ public enum CommandState EXCEPTION } - public interface ICommandBase : IObservable + public interface ICommandBase { public CommandState State { get; } public Exception? LastException { get; } public bool PrepareModal(); + public IDisposable Subscribe(Action stateHasChanged); } public interface ICommand : ICommandBase diff --git a/RxBlazorLightCore/Core/RxExtensions.cs b/RxBlazorLightCore/Core/RxExtensions.cs new file mode 100644 index 0000000..5e51c2c --- /dev/null +++ b/RxBlazorLightCore/Core/RxExtensions.cs @@ -0,0 +1,51 @@ + +using System.Reactive; +using System.Reactive.Linq; + +namespace RxBlazorLightCore +{ + public static class RxExtensions + { + public static bool Preparing(this ICommandBase commandBase) + { + return commandBase.State is CommandState.PREPARING; + } + + public static bool Executing(this ICommandBase commandBase) + { + return commandBase.State is CommandState.EXECUTING; + } + public static bool Executed(this ICommandBase commandBase) + { + return commandBase.State is CommandState.EXECUTED; + } + public static bool NotExecuted(this ICommandBase commandBase) + { + return commandBase.State is CommandState.NOT_EXECUTED; + } + + public static bool Canceled(this ICommandBase commandBase) + { + return commandBase.State is CommandState.CANCELED; + } + + public static bool Exception(this ICommandBase commandBase) + { + return commandBase.State is CommandState.EXCEPTION; + } + + public static bool Running(this ICommandBase commandBase) + { + return commandBase.State is CommandState.PREPARING || commandBase.State is CommandState.EXECUTING; + } + + public static bool Changing(this IInput input) + { + return input.State is InputState.CHANGING; + } + public static bool Changed(this IInput input) + { + return input.State is InputState.CHANGED; + } + } +} diff --git a/RxBlazorLightCore/Core/Service.cs b/RxBlazorLightCore/Core/Service.cs index 7dbcf7a..5f7c1de 100644 --- a/RxBlazorLightCore/Core/Service.cs +++ b/RxBlazorLightCore/Core/Service.cs @@ -52,33 +52,23 @@ public async ValueTask OnContextReadyAsync() throw new InvalidOperationException("Nested RxBLService context not allowed!"); } Initialized = true; - await InitializeContextAsync(); + await ContextReadyAsync(); StateHasChanged(); } - protected virtual ValueTask InitializeContextAsync() + protected virtual ValueTask ContextReadyAsync() { return ValueTask.CompletedTask; } - public void OnContextDisposed() - { - DisposeContext(); - Initialized = false; - } - - protected virtual void DisposeContext() - { - } - public void ResetExceptions() { _serviceExceptions.Clear(); } - protected static IInput CreateInput(S service, T value) where S : RxBLService + protected static IInput CreateInput(S service, T? value, Func? canChange = null) where S : RxBLService { - return Input.Create(service, value); + return Input.Create(service, value, canChange); } } } diff --git a/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs b/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs index 9069e73..8e45c1f 100644 --- a/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs +++ b/RxMudBlazorLight/Dialogs/DialogAsyncPRx.razor.cs @@ -102,10 +102,10 @@ private void BeforeExecutionDo() if (_buttonRef?.RxCommandAsync is not null && _buttonDisposable is null) { - _buttonDisposable = _buttonRef.RxCommandAsync.Subscribe(cs => + _buttonDisposable = _buttonRef.RxCommandAsync.Subscribe(() => { InvokeAsync(StateHasChanged); - _canceled = cs is CommandState.CANCELED; + _canceled = RxCommandAsync.State is CommandState.CANCELED; }); } diff --git a/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs b/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs index 7a83f4d..1f9d976 100644 --- a/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs +++ b/RxMudBlazorLight/Dialogs/DialogAsyncRx.razor.cs @@ -98,10 +98,10 @@ private void BeforeExecutionDo() if (_buttonRef?.RxCommandAsync is not null && _buttonDisposable is null) { - _buttonDisposable = _buttonRef.RxCommandAsync.Subscribe(cs => + _buttonDisposable = _buttonRef.RxCommandAsync.Subscribe(() => { InvokeAsync(StateHasChanged); - _canceled = cs is CommandState.CANCELED; + _canceled = RxCommandAsync.State is CommandState.CANCELED; }); } diff --git a/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor b/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor index b71612d..340c795 100644 --- a/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor +++ b/RxMudBlazorLight/Inputs/MudAutocompleteRx.razor @@ -11,13 +11,14 @@ protected override void OnParametersSet() { - Value = RxInput.Value; - ArgumentNullException.ThrowIfNull(Value); + if (RxInput.State is not InputState.CHANGING && RxInput.HasValue()) + { + Value = RxInput.Value; + Text = Value.ToString(); - Text = Value.ToString(); - - ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); - Disabled = !RxInput.CanChange(); + ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); + } + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor b/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor index 3704405..1189f3b 100644 --- a/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor +++ b/RxMudBlazorLight/Inputs/MudCheckBoxRx.razor @@ -11,16 +11,18 @@ protected override void OnParametersSet() { - Value = RxInput.Value; - ValueChanged = EventCallback.Factory.Create(this, v => + if (RxInput.State is not InputState.CHANGING) { - if (v is not null) + Value = RxInput.Value; + ValueChanged = EventCallback.Factory.Create(this, v => { - RxInput.Value = v; - } - }); - - Disabled = !RxInput.CanChange(); + if (v is not null) + { + RxInput.Value = v; + } + }); + } + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor b/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor index 119e551..55daec3 100644 --- a/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor +++ b/RxMudBlazorLight/Inputs/MudNumericFieldRx.razor @@ -9,14 +9,20 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - protected override void OnParametersSet() + protected override void OnInitialized() { - Value = RxInput.Value; - ArgumentNullException.ThrowIfNull(Value); - - Text = Value.ToString(); + base.OnInitialized(); ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); - Disabled = !RxInput.CanChange(); + } + + protected override void OnParametersSet() + { + if (RxInput.State is not InputState.CHANGING && RxInput.HasValue()) + { + Value = RxInput.Value; + Text = Value.ToString(); + } + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLight/Inputs/MudRatingRx.razor b/RxMudBlazorLight/Inputs/MudRatingRx.razor index fc18954..6ccbb5f 100644 --- a/RxMudBlazorLight/Inputs/MudRatingRx.razor +++ b/RxMudBlazorLight/Inputs/MudRatingRx.razor @@ -11,15 +11,17 @@ protected override void OnInitialized() { base.OnInitialized(); - SelectedValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); } protected override void OnParametersSet() { - SelectedValue = RxInput.Value; - Disabled = !RxInput.CanChange(); + if (RxInput.State is not InputState.CHANGING && RxInput.HasValue()) + { + SelectedValue = RxInput.Value; + } + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } } diff --git a/RxMudBlazorLight/Inputs/MudSliderRx.razor b/RxMudBlazorLight/Inputs/MudSliderRx.razor index 1b1debe..acd01e7 100644 --- a/RxMudBlazorLight/Inputs/MudSliderRx.razor +++ b/RxMudBlazorLight/Inputs/MudSliderRx.razor @@ -9,12 +9,20 @@ private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - protected override void OnParametersSet() + protected override void OnInitialized() { - Value = RxInput.Value; + base.OnInitialized(); ValueChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); - Disabled = !RxInput.CanChange(); + } + + protected override void OnParametersSet() + { + if (RxInput.State is not InputState.CHANGING) + { + Value = RxInput.Value; + } + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } } diff --git a/RxMudBlazorLight/Inputs/MudSwitchRx.razor b/RxMudBlazorLight/Inputs/MudSwitchRx.razor index e4e5b5a..68ca4ee 100644 --- a/RxMudBlazorLight/Inputs/MudSwitchRx.razor +++ b/RxMudBlazorLight/Inputs/MudSwitchRx.razor @@ -11,16 +11,19 @@ protected override void OnParametersSet() { - Value = RxInput.Value; - ValueChanged = EventCallback.Factory.Create(this, v => + if (RxInput.State is not InputState.CHANGING) { - if (v is not null) + Value = RxInput.Value; + ValueChanged = EventCallback.Factory.Create(this, v => { - RxInput.Value = v; - } - }); + if (v is not null) + { + RxInput.Value = v; + } + }); + } - Disabled = !RxInput.CanChange(); + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLight/Inputs/MudTextFieldRx.razor b/RxMudBlazorLight/Inputs/MudTextFieldRx.razor index ea48a4f..b83a899 100644 --- a/RxMudBlazorLight/Inputs/MudTextFieldRx.razor +++ b/RxMudBlazorLight/Inputs/MudTextFieldRx.razor @@ -17,10 +17,13 @@ protected override void OnParametersSet() { - Value = RxInput.Value; - Text = Value?.ToString(); + if (RxInput.State is not InputState.CHANGING && RxInput.HasValue()) + { + Value = RxInput.Value; + Text = Value.ToString(); + } - Disabled = !RxInput.CanChange(); + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs index 1042e28..f325179 100644 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs +++ b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupBaseRx.cs @@ -46,9 +46,12 @@ protected override void OnParametersSet() }; } - Value = RxInputGroupBase.Value; - ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.Value = v); - Disabled = !RxInputGroupBase.CanChange(); + if (RxInputGroupBase.State is not InputState.CHANGING) + { + Value = RxInputGroupBase.Value; + ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.Value = v); + } + Disabled = !RxInputGroupBase.CanChange() || RxInputGroupBase.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor index 9269356..a5f55fd 100644 --- a/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor +++ b/RxMudBlazorLight/Inputs/Radio/MudRadioGroupRx.razor @@ -8,13 +8,10 @@ public required IInputGroup RxInputGroup { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroup? _rxInputGroup; protected override void OnInitialized() { - _rxInputGroup = RxInputGroup; - RxInputGroupBase = _rxInputGroup; - + RxInputGroupBase = RxInputGroup; base.OnInitialized(); } } diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs b/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs index 3e23db5..d586afa 100644 --- a/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs +++ b/RxMudBlazorLight/Inputs/Select/MudSelectBaseRx.cs @@ -17,8 +17,11 @@ protected override void OnParametersSet() { ArgumentNullException.ThrowIfNull(RxInputGroupBase); - Value = RxInputGroupBase.Value; - Text = Value?.ToString(); + if (RxInputGroupBase.HasValue()) + { + Value = RxInputGroupBase.Value; + Text = Value.ToString(); + } ValueChanged = EventCallback.Factory.Create(this, v => RxInputGroupBase.Value = v); Disabled = !RxInputGroupBase.CanChange(); @@ -45,6 +48,8 @@ protected override void OnParametersSet() }; } + Disabled = !RxInputGroupBase.CanChange() || RxInputGroupBase.State is InputState.CHANGING; + base.OnParametersSet(); } @@ -52,11 +57,11 @@ protected override void OnAfterRender(bool firstRender) { ArgumentNullException.ThrowIfNull(RxInputGroupBase); - if (!_initialized && firstRender) + if (!_initialized && firstRender && RxInputGroupBase.HasValue()) { _initialized = true; Value = RxInputGroupBase.Value; - Text = Value?.ToString(); + Text = Value.ToString(); } base.OnAfterRender(firstRender); diff --git a/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor b/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor index 6624504..c38ca36 100644 --- a/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor +++ b/RxMudBlazorLight/Inputs/Select/MudSelectRx.razor @@ -8,13 +8,10 @@ public required IInputGroup RxInputGroup { get; init; } private RenderFragment RenderBase() => builder => base.BuildRenderTree(builder); - private IInputGroup? _rxInputGroup; protected override void OnInitialized() { - _rxInputGroup = RxInputGroup; - RxInputGroupBase = _rxInputGroup; - + RxInputGroupBase = RxInputGroup; base.OnInitialized(); } } diff --git a/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor b/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor index 5aeea48..8e3457a 100644 --- a/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor +++ b/RxMudBlazorLight/ToggleIconButtons/MudToggleIconButtonRx.razor @@ -21,7 +21,7 @@ { Toggled = RxInput.Value; ToggledChanged = EventCallback.Factory.Create(this, v => RxInput.Value = v); - Disabled = !RxInput.CanChange(); + Disabled = !RxInput.CanChange() || RxInput.State is InputState.CHANGING; base.OnParametersSet(); } diff --git a/RxMudBlazorLightTestBase/Components/ButtonTest.razor b/RxMudBlazorLightTestBase/Components/ButtonTest.razor index 5397682..f9626fe 100644 --- a/RxMudBlazorLightTestBase/Components/ButtonTest.razor +++ b/RxMudBlazorLightTestBase/Components/ButtonTest.razor @@ -2,70 +2,70 @@ Counter - @Service.State.Value.State - - - - - - - Current count: @Service.Count - - - Increment - Add 5 - - - IncrementAsync - - - - AddAsync 2 - - - - - - Increment - Add 5 - CmdDialogClick()) OnTouch=@(() => CmdDialogClick())>IncrementAsync - CmdDialogClick(2)) OnTouch=@(() => CmdDialogClick(2))>AddAsync 2 - - - - - - - - - - - - - - - - - - - - - - CmdDialogClick())>Increment AsyncDialog - CmdDialogClick(10))>Add AsyncDialog 10 - Service.ChangeState("TEST1"))>Change State to Test1 - Service.ChangeState("TEST2"))>Change State to Test2 - - - - @if (Service.Exceptions.Any()) + @Service.State.Value?.State + + + + + + + Current count: @Service.Count + + + Increment + Add 5 + + + IncrementAsync + + + + AddAsync 2 + + + + + + Increment + Add 5 + CmdDialogClick()) OnTouch=@(() => CmdDialogClick())>IncrementAsync + CmdDialogClick(2)) OnTouch=@(() => CmdDialogClick(2))>AddAsync 2 + + + + + + + + + + + + + + + + + + + + + + CmdDialogClick())>Increment AsyncDialog + CmdDialogClick(10))>Add AsyncDialog 10 + Service.ChangeState("TEST1"))>Change State to Test1 + Service.ChangeState("TEST2"))>Change State to Test2 + + + + @if (Service.Exceptions.Any()) { @GetExceptions() - Service.ResetExceptions())>Reset Exceptions - + Service.ResetExceptions())>Reset Exceptions + } diff --git a/RxMudBlazorLightTestBase/Components/InputTest.razor b/RxMudBlazorLightTestBase/Components/InputTest.razor index a254ffc..14a1dec 100644 --- a/RxMudBlazorLightTestBase/Components/InputTest.razor +++ b/RxMudBlazorLightTestBase/Components/InputTest.razor @@ -8,6 +8,8 @@ Current count: @Service.Count + Service.IncrementValue.Cancel())>Cancel Increment Change + Size.Large) PlacementCallback=@(_ => Placement.Start) /> @@ -48,6 +50,16 @@ + + + @if (Service.Exceptions.Any()) + { + + @GetExceptions() + Service.ResetExceptions())>Reset Exceptions + + } + @code { @@ -60,15 +72,15 @@ protected override void OnInitialized() { - _disposeBag.Add(Service.CanIncrementCheck.Subscribe(val => + _disposeBag.Add(Service.CanIncrementCheck.Subscribe(() => { - _imageSrc = val ? "https://upload.wikimedia.org/wikipedia/commons/4/41/Flag_of_Austria.svg" : + _imageSrc = Service.CanIncrementCheck.Value ? "https://upload.wikimedia.org/wikipedia/commons/4/41/Flag_of_Austria.svg" : "https://upload.wikimedia.org/wikipedia/commons/4/4b/Flag_of_Sweden_fixed.svg"; })); - _disposeBag.Add(Service.Simple.Subscribe(cs => + _disposeBag.Add(Service.Simple.Subscribe(() => { - if (cs is CommandState.EXECUTED) + if (Service.Simple.Executed()) { _simpleExecutions++; } @@ -127,6 +139,11 @@ return states.Where(x => x.Contains(value, StringComparison.InvariantCultureIgnoreCase)); } + private string GetExceptions() + { + return Service.Exceptions.Aggregate("", (p, n) => p + n.Message + ", ").TrimEnd(new[] { ' ', ',' }); + } + public void Dispose() { _disposeBag.Dispose(); diff --git a/RxMudBlazorLightTestBase/Components/TestPlayground.razor b/RxMudBlazorLightTestBase/Components/TestPlayground.razor index 7e5e39b..57af182 100644 --- a/RxMudBlazorLightTestBase/Components/TestPlayground.razor +++ b/RxMudBlazorLightTestBase/Components/TestPlayground.razor @@ -16,7 +16,6 @@ @($"Equals async executions {_equalsAsyncExecutions}") EqualsTest - _showNestedTimer = !_showNestedTimer)>Throw nested RxServiceException @if (Service.Exceptions.Any()) { @@ -36,22 +35,21 @@ private long _equalsAsyncExecutions = 0; private CompositeDisposable _disposeBag = new(); - private bool _showNestedTimer = false; protected override void OnInitialized() { - _disposeBag.Add(Service.EqualsTest.Subscribe(cs => + _disposeBag.Add(Service.EqualsTest.Subscribe(() => { - if (cs is CommandState.EXECUTED) + if (Service.EqualsTest.Executed()) { _equalsExecutions++; } StateHasChanged(); })); - _disposeBag.Add(Service.EqualsTestAsync.Subscribe(cs => + _disposeBag.Add(Service.EqualsTestAsync.Subscribe(() => { - if (cs is CommandState.EXECUTED) + if (Service.EqualsTestAsync.Executed()) { _equalsAsyncExecutions++; } diff --git a/RxMudBlazorLightTestBase/Service/TestService.Input.cs b/RxMudBlazorLightTestBase/Service/TestService.Input.cs index 58806a1..456dba6 100644 --- a/RxMudBlazorLightTestBase/Service/TestService.Input.cs +++ b/RxMudBlazorLightTestBase/Service/TestService.Input.cs @@ -6,8 +6,12 @@ public sealed partial class TestService { public class IncrementValueIP(TestService service, int value) : Input(service, value) { - protected override void OnValueChanged(int oldValue, int newValue) + protected override async ValueTask OnValueChangedAsync(int oldValue, int newValue, CancellationToken cancellationToken) { + await Task.Delay(3000, cancellationToken); + + ArgumentOutOfRangeException.ThrowIfGreaterThan(newValue, 40); + Service.Count = newValue; } @@ -64,6 +68,11 @@ public override TestColor[] GetItems() return _colors; } + protected override async ValueTask OnValueChangedAsync(TestColor? oldValue, TestColor newValue, CancellationToken cancellationToken) + { + await Task.Delay(2000, cancellationToken); + } + public override bool IsItemDisabled(int index) { return index == 1 && Service.CanIncrementCheck.Value; diff --git a/RxMudBlazorLightTestBase/Service/TestService.cs b/RxMudBlazorLightTestBase/Service/TestService.cs index b436002..e0ac289 100644 --- a/RxMudBlazorLightTestBase/Service/TestService.cs +++ b/RxMudBlazorLightTestBase/Service/TestService.cs @@ -83,7 +83,7 @@ public TestService(IServiceProvider _) { Console.WriteLine("TestService Create"); - State = CreateInput(this, new StateInfo("None")); + State = CreateInput(this, (StateInfo?)null); Increment = new IncrementCMD(this); AddAsync = new AddAsyncCMD(this); @@ -116,22 +116,20 @@ public override IRxBLScope CreateScope() return new SubScope(this); } - protected override async ValueTask InitializeContextAsync() + protected override async ValueTask ContextReadyAsync() { Console.WriteLine("TestService OnContextInitialized"); await Task.Delay(3000); _canIncrement = true; - } - - protected override void DisposeContext() - { - _canIncrement = false; - Console.WriteLine("TestService OnContextDisposed"); + State.Value = new StateInfo("Initialize"); } public void ChangeState(string state) - { - State.Value = State.Value with { State = state }; + { + if (State.HasValue()) + { + State.Value = State.Value with { State = state }; + } } public IInputGroup GetPizzas1()