diff --git a/src/BootstrapBlazor/BootstrapBlazor.csproj b/src/BootstrapBlazor/BootstrapBlazor.csproj index bf5f5cb5aca..ee9e70bc063 100644 --- a/src/BootstrapBlazor/BootstrapBlazor.csproj +++ b/src/BootstrapBlazor/BootstrapBlazor.csproj @@ -1,7 +1,7 @@ - 9.4.3-beta04 + 9.4.4 diff --git a/src/BootstrapBlazor/Components/Dialog/Dialog.razor b/src/BootstrapBlazor/Components/Dialog/Dialog.razor index d237e397a31..749452aa414 100644 --- a/src/BootstrapBlazor/Components/Dialog/Dialog.razor +++ b/src/BootstrapBlazor/Components/Dialog/Dialog.razor @@ -1,7 +1,8 @@ @namespace BootstrapBlazor.Components @inherits BootstrapComponentBase - + @for (var index = 0; index < DialogParameters.Keys.Count; index++) { @RenderDialog(index, DialogParameters.Keys.ElementAt(index)) diff --git a/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs b/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs index aaec0956cb0..296f1a54100 100644 --- a/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs +++ b/src/BootstrapBlazor/Components/Dialog/Dialog.razor.cs @@ -6,53 +6,42 @@ namespace BootstrapBlazor.Components; /// -/// Dialog 对话框组件 +/// Dialog component /// public partial class Dialog : IDisposable { - /// - /// 获得/设置 Modal 容器组件实例 - /// - [NotNull] - private Modal? ModalContainer { get; set; } - - /// - /// 获得/设置 弹出对话框实例集合 - /// - private Dictionary, (bool IsKeyboard, bool IsBackdrop)> DialogParameters { get; } = []; - - private bool IsKeyboard { get; set; } - - private bool IsBackdrop { get; set; } - - /// - /// DialogServices 服务实例 - /// [Inject] [NotNull] private DialogService? DialogService { get; set; } [NotNull] - private Func? OnShownAsync { get; set; } + private Modal? _modal = null; + + [NotNull] + private Func? _onShownAsync = null; [NotNull] - private Func? OnCloseAsync { get; set; } + private Func? _onCloseAsync = null; - private Dictionary? CurrentParameter { get; set; } + private readonly Dictionary, (bool IsKeyboard, bool IsBackdrop)> DialogParameters = []; + private Dictionary? _currentParameter; + private bool _isKeyboard = false; + private bool _isBackdrop = false; + private bool _isFade = true; /// - /// OnInitialized 方法 + /// /// protected override void OnInitialized() { base.OnInitialized(); - // 注册 Dialog 弹窗事件 + // Register Dialog popup event DialogService.Register(this, Show); } /// - /// OnAfterRenderAsync 方法 + /// /// /// /// @@ -60,15 +49,15 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { await base.OnAfterRenderAsync(firstRender); - if (CurrentParameter != null) + if (_currentParameter != null) { - await ModalContainer.Show(); + await _modal.Show(); } } private async Task Show(DialogOption option) { - OnShownAsync = async () => + _onShownAsync = async () => { if (option.OnShownAsync != null) { @@ -76,33 +65,34 @@ private async Task Show(DialogOption option) } }; - OnCloseAsync = async () => + _onCloseAsync = async () => { - // 回调 OnCloseAsync + // Callback OnCloseAsync if (option.OnCloseAsync != null) { await option.OnCloseAsync(); } - // 移除当前 DialogParameter - if (CurrentParameter != null) + // Remove current DialogParameter + if (_currentParameter != null) { - DialogParameters.Remove(CurrentParameter); + DialogParameters.Remove(_currentParameter); - // 多弹窗支持 + // Support for multiple dialogs var p = DialogParameters.LastOrDefault(); - CurrentParameter = p.Key; - IsKeyboard = p.Value.IsKeyboard; - IsBackdrop = p.Value.IsBackdrop; + _currentParameter = p.Key; + _isKeyboard = p.Value.IsKeyboard; + _isBackdrop = p.Value.IsBackdrop; StateHasChanged(); } }; - IsKeyboard = option.IsKeyboard; - IsBackdrop = option.IsBackdrop; + _isKeyboard = option.IsKeyboard; + _isBackdrop = option.IsBackdrop; + _isFade = option.IsFade; - option.Modal = ModalContainer; + option.Modal = _modal; var parameters = option.ToAttributes(); var content = option.BodyTemplate ?? option.Component?.Render(); @@ -163,11 +153,11 @@ private async Task Show(DialogOption option) } } - // 保存当前 Dialog 参数 - CurrentParameter = parameters; + // Save current Dialog parameters + _currentParameter = parameters; - // 添加 ModalDialog 到容器中 - DialogParameters.Add(parameters, (IsKeyboard, IsBackdrop)); + // Add ModalDialog to the container + DialogParameters.Add(parameters, (_isKeyboard, _isBackdrop)); await InvokeAsync(StateHasChanged); } @@ -180,7 +170,7 @@ private static RenderFragment RenderDialog(int index, Dictionary }; /// - /// Dispose 方法 + /// Dispose method /// /// protected virtual void Dispose(bool disposing) @@ -192,7 +182,7 @@ protected virtual void Dispose(bool disposing) } /// - /// Dispose 方法 + /// /// public void Dispose() { diff --git a/src/BootstrapBlazor/Components/Dialog/DialogOption.cs b/src/BootstrapBlazor/Components/Dialog/DialogOption.cs index 13b9674d680..3ebbc45547d 100644 --- a/src/BootstrapBlazor/Components/Dialog/DialogOption.cs +++ b/src/BootstrapBlazor/Components/Dialog/DialogOption.cs @@ -6,194 +6,199 @@ namespace BootstrapBlazor.Components; /// -/// Dialog 组件配置类 +/// Configuration class for the Dialog component /// public class DialogOption { /// - /// 获得/设置 相关弹窗实例 + /// Gets or sets the related modal instance /// internal Modal? Modal { get; set; } /// - /// 获得/设置 弹窗标题 + /// Gets or sets the dialog title /// public string? Title { get; set; } /// - /// 获得/设置 弹窗自定义样式 + /// Gets or sets the custom style of the dialog /// public string? Class { get; set; } /// - /// 获得/设置 弹窗大小 + /// Gets or sets the size of the dialog /// public Size Size { get; set; } = Size.ExtraExtraLarge; /// - /// 获得/设置 全屏弹窗 默认 None + /// Gets or sets the full screen size of the dialog, default is None /// - /// 为保证功能正常,设置值后 均不可用 + /// To ensure functionality, when this value is set, , , and are not available public FullScreenSize FullScreenSize { get; set; } = FullScreenSize.None; /// - /// 获得/设置 是否显示最大化按钮 默认 false 不显示 + /// Gets or sets whether to show the maximize button, default is false /// - /// 为保证功能正常,设置值为 true 后 均不可用 + /// To ensure functionality, when this value is set to true, and are not available public bool ShowMaximizeButton { get; set; } /// - /// 获得/设置 是否垂直居中 默认为 true + /// Gets or sets whether the dialog is vertically centered, default is true /// public bool IsCentered { get; set; } = true; /// - /// 获得/设置 是否弹窗正文超长时滚动 默认为 false + /// Gets or sets whether the dialog content scrolls when it is too long, default is false /// public bool IsScrolling { get; set; } = false; /// - /// 获得/设置 是否显示调整大小按钮 默认为 false + /// Gets or sets whether to show the resize button, default is false /// public bool ShowResize { get; set; } /// - /// 获得/设置 是否显示关闭按钮 默认为 true + /// Gets or sets whether to show the close button, default is true /// public bool ShowCloseButton { get; set; } = true; /// - /// 获得/设置 是否显示 Header 关闭按钮 默认为 true + /// Gets or sets whether to show the header close button, default is true /// public bool ShowHeaderCloseButton { get; set; } = true; /// - /// 获得/设置 是否支持键盘 ESC 关闭当前弹窗 默认 true 支持 + /// Gets or sets whether to enable fade animation, default is true + /// + public bool IsFade { get; set; } = true; + + /// + /// Gets or sets whether to support closing the dialog with the ESC key, default is true /// public bool IsKeyboard { get; set; } = true; /// - /// 获得/设置 是否支持点击遮罩关闭弹窗 默认 false + /// Gets or sets whether to support closing the dialog by clicking the backdrop, default is false /// public bool IsBackdrop { get; set; } /// - /// 获得/设置 是否显示 Footer 默认为 true + /// Gets or sets whether to show the footer, default is true /// public bool ShowFooter { get; set; } = true; /// - /// 获得/设置 是否显示打印按钮 默认 false 不显示 + /// Gets or sets whether to show the print button, default is false /// public bool ShowPrintButton { get; set; } /// - /// 获得/设置 是否显示保存按钮 默认 false 不显示 + /// Gets or sets whether to show the save button, default is false /// public bool ShowSaveButton { get; set; } /// - /// 获得/设置 打印按钮是否显示在 Header 中 默认 false 不显示 + /// Gets or sets whether to show the print button in the header, default is false /// public bool ShowPrintButtonInHeader { get; set; } /// - /// 获得/设置 Header 中打印按钮显示文字 默认为资源文件中 打印 + /// Gets or sets the text of the print button in the header, default is "Print" from the resource file /// public string? PrintButtonText { get; set; } /// - /// 获得/设置 相关连数据,多用于传值使用 + /// Gets or sets the related data, mostly used for passing values /// public object? BodyContext { get; set; } /// - /// 获得/设置 ModalBody 组件 + /// Gets or sets the ModalBody component /// public RenderFragment? BodyTemplate { get; set; } /// - /// 获得/设置 ModalFooter 组件 + /// Gets or sets the ModalFooter component /// public RenderFragment? FooterTemplate { get; set; } /// - /// 获得/设置 ModalHeader 组件模板 + /// Gets or sets the ModalHeader component template /// public RenderFragment? HeaderTemplate { get; set; } /// - /// 获得/设置 ModalHeader 组件自定义按钮 + /// Gets or sets the custom buttons in the ModalHeader component /// public RenderFragment? HeaderToolbarTemplate { get; set; } /// - /// 获得/设置 自定义组件 + /// Gets or sets the custom component /// public BootstrapDynamicComponent? Component { get; set; } /// - /// 获得/设置 保存按钮图标 默认 null 使用当前主题图标 + /// Gets or sets the icon of the save button, default is null and uses the current theme icon /// public string? SaveButtonIcon { get; set; } /// - /// 获得/设置 保存按钮文本 + /// Gets or sets the text of the save button /// public string? SaveButtonText { get; set; } /// - /// 获得/设置 保存按钮回调方法 + /// Gets or sets the callback method for the save button /// public Func>? OnSaveAsync { get; set; } /// - /// 获得/设置 关闭按钮图标 默认 null 使用当前主题图标 + /// Gets or sets the icon of the close button, default is null and uses the current theme icon /// public string? CloseButtonIcon { get; set; } /// - /// 获得/设置 关闭按钮文本 + /// Gets or sets the text of the close button /// public string? CloseButtonText { get; set; } /// - /// 获得/设置 关闭弹窗回调方法 + /// Gets or sets the callback method for closing the dialog /// public Func? OnCloseAsync { get; set; } /// - /// 获得/设置 保存成功后是否自动关闭弹窗 默认 true 自动关闭 + /// Gets or sets whether to automatically close the dialog after saving successfully, default is true /// public bool IsAutoCloseAfterSave { get; set; } = true; /// - /// 获得/设置 是否可以拖拽弹窗 默认 false 不可以拖动 + /// Gets or sets whether the dialog can be dragged, default is false /// public bool IsDraggable { get; set; } /// - /// 获得/设置 弹窗已显示时回调此方法 + /// Gets or sets the callback method when the dialog is shown /// public Func? OnShownAsync { get; set; } /// - /// 获得/设置 是否显示导出 Pdf 按钮 默认为 false 不显示 + /// Gets or sets whether to show the export PDF button, default is false /// public bool ShowExportPdfButton { get; set; } /// - /// 获得/设置 Header 中是否显示导出 Pdf 按钮 默认 false 不显示 + /// Gets or sets whether to show the export PDF button in the header, default is false /// public bool ShowExportPdfButtonInHeader { get; set; } /// - /// 获得/设置 导出 Pdf 按钮配置项 + /// Gets or sets the configuration options for the export PDF button /// public ExportPdfButtonOptions? ExportPdfButtonOptions { get; set; } /// - /// 关闭弹窗方法 + /// Method to close the dialog /// public async Task CloseDialogAsync() { @@ -204,7 +209,7 @@ public async Task CloseDialogAsync() } /// - /// 将参数转换为组件属性方法 + /// Method to convert parameters to component attributes /// /// public Dictionary ToAttributes() diff --git a/test/UnitTest/Components/DialogTest.cs b/test/UnitTest/Components/DialogTest.cs index 30399084d30..067aca4a161 100644 --- a/test/UnitTest/Components/DialogTest.cs +++ b/test/UnitTest/Components/DialogTest.cs @@ -58,6 +58,7 @@ await cut.InvokeAsync(() => dialog.Show(new DialogOption() ShowExportPdfButton = true, ShowExportPdfButtonInHeader = true, ExportPdfButtonOptions = new(), + IsFade = false, OnCloseAsync = () => { closed = true; @@ -65,6 +66,9 @@ await cut.InvokeAsync(() => dialog.Show(new DialogOption() } })); + // 由于设置了 IsFade=false Modal 不应该渲染 fade 样式 + Assert.DoesNotContain("modal fade", modal.Markup); + // 由于设置了 ShowMaximizeButton 导致 ShowResize 参数失效 Assert.DoesNotContain(" m.IsFade, false); }); Assert.DoesNotContain("static", cut.Markup); + Assert.DoesNotContain("modal fade", cut.Markup); cut.SetParametersAndRender(pb => { @@ -34,6 +35,7 @@ public void Toggle_Ok() pb.AddChildContent(); }); cut.InvokeAsync(async () => await cut.Instance.Toggle()); + Assert.Contains("modal fade", cut.Markup); Assert.Contains("modal-dialog", cut.Markup); }