Enterprise-level component library based on Bootstrap and Blazor

star nuget master download license repo commit

Dialog 对话框组件

通过注入服务调用 Show 方法弹出窗口进行人机交互

<Dialog />

基本用法

通过设置 DialogOption 属性对模态框进行基本属性设置

Demo

弹出复杂组件

通过调用 Show<Counter>() 来弹出一个自定义组件

Demo

本例中弹出对话框中包含一个示例网站的自带 Counter 组件

弹窗传参

通过设置 BodyContext 属性值,可以把参数传递给弹窗中的组件内

Demo

本例中点击按钮时设置 BodyContext 值为 我是传参,弹窗内容为自定义组件 DemoComponent,组件内通过级联参数获取到其值

实战应用

本例中通过传递一个主键,在弹窗内的组件通过此主键进行数据查询,并将结果显示在弹窗内

Demo

代码关闭弹窗

本例讲解如何通过代码打开与关闭弹窗

Demo

利用弹窗参数 DialogOption 实例,弹窗弹出后实例中的 Dialog 属性值即为当前弹窗句柄,通过调用其 Toggle/Close 方法即可关闭弹窗

多级弹窗

点击弹窗内部按钮继续弹出对话窗

Demo

功能介绍

  • 点击按钮弹出对话窗
  • 切换弹窗内 Tab 组件的第三个标签页 角色管理
  • 点击标签页中的弹窗继续弹出对话框
  • 关闭当前对话框后之前打开的对话框 保持状态

模态对话框

通过 ShowModal 方法弹出线程阻塞模式的对话框

Demo

功能介绍

  • 点击按钮弹出模态弹窗
  • 更改模态弹窗内数值点击 确认 按钮时数值 更新
  • 更改模态弹窗内数值点击 取消 或者 关闭 按钮时数值 不更新
  • 再次点击弹出模态弹窗时,数值保持一致

实战演练

模拟一个邮件应用,弹窗选择收件人后填入下方的收件人框。

Demo

功能介绍

  • 点击按钮弹出模态弹窗
  • 通过级联传参 BodyContext 传递 10 到弹窗中初始化数据
  • 选中 Table 组件中的行数据,通过双向绑定对 SelectedRows 数据进行 更新
  • 点击 选中 按钮通过双向绑定对 Emails 数据进行 更新
  • 点击 取消 或者 关闭 按钮时 Emails不更新
  • 再次点击弹出模态弹窗时,组件内行选中状态保持一致
  • 弹窗中未选择用户时禁止关闭弹窗

DialogOption 属性

Loading...
@page "/dialogs"

<h3>Dialog 对话框组件</h3>

<h4>通过注入服务调用 <code>Show</code> 方法弹出窗口进行人机交互</h4>

<Tips class="mt-3">
    <p>
        本组件使用注入服务的形式提供功能,使用时用户体验效果非常舒适,随时随地的调用,需要在使用本组件的页面中内置 <code>Dialog</code> 组件,或者在 <code>MainLayout</code> 主布局组件中内置,示例代码如下:
    </p>
</Tips>

<Pre>&lt;Dialog /&gt;</Pre>

<Block Title="基本用法" Introduction="通过设置 <code>DialogOption</code> 属性对模态框进行基本属性设置">
    <Button @onclick="@OnClick">点击打开 Dialog</Button>
</Block>

<Block Title="弹出复杂组件" Introduction="通过调用 <code>Show&lt;Counter&gt;()</code> 来弹出一个自定义组件">
    <p>
        本例中弹出对话框中包含一个示例网站的自带 <code>Counter</code> 组件
    </p>
    <Button @onclick="@OnClickCounter">点击打开 Dialog</Button>
</Block>

<Block Title="弹窗传参" Introduction="通过设置 <code>BodyContext</code> 属性值,可以把参数传递给弹窗中的组件内">
    <p>
        本例中点击按钮时设置 <code>BodyContext</code> 值为 <code>我是传参</code>,弹窗内容为自定义组件 <code>DemoComponent</code>,组件内通过级联参数获取到其值
    </p>
    <Button @onclick="@OnClickParameter">Dialog 传参示例</Button>
</Block>

<Block Title="实战应用" Introduction="本例中通过传递一个主键,在弹窗内的组件通过此主键进行数据查询,并将结果显示在弹窗内">
    <div class="form-inline">
        <div class="row">
            <div class="form-group col-12 col-sm-6">
                <Select @bind-Value="@DataPrimaryId" DisplayText="主键参数" ShowLabel="true">
                    <Options>
                        <SelectOption Text="1" Value="1"></SelectOption>
                        <SelectOption Text="2" Value="2"></SelectOption>
                        <SelectOption Text="3" Value="3"></SelectOption>
                        <SelectOption Text="4" Value="4"></SelectOption>
                        <SelectOption Text="5" Value="5"></SelectOption>
                        <SelectOption Text="6" Value="6"></SelectOption>
                        <SelectOption Text="7" Value="7"></SelectOption>
                        <SelectOption Text="8" Value="8"></SelectOption>
                        <SelectOption Text="9" Value="9"></SelectOption>
                        <SelectOption Text="10" Value="10"></SelectOption>
                    </Options>
                </Select>
            </div>
            <div class="form-group col-12 col-sm-6">
                <Button @onclick="@OnClickShowDataById">弹窗</Button>
            </div>
        </div>
    </div>
</Block>

<Block Title="代码关闭弹窗" Introduction="本例讲解如何通过代码打开与关闭弹窗">
    <p>利用弹窗参数 <code>DialogOption</code> 实例,弹窗弹出后实例中的 <code>Dialog</code> 属性值即为当前弹窗句柄,通过调用其 <code>Toggle/Close</code> 方法即可关闭弹窗</p>

    <Button @onclick="@Show">Dialog</Button>
</Block>

<Block Title="多级弹窗" Introduction="点击弹窗内部按钮继续弹出对话窗">
    <p>功能介绍</p>
    <ul class="ul-demo">
        <li>点击按钮弹出对话窗</li>
        <li>切换弹窗内 <code>Tab</code> 组件的第三个标签页 <b>角色管理</b></li>
        <li>点击标签页中的弹窗继续弹出对话框</li>
        <li>关闭当前对话框后之前打开的对话框 <b>保持状态</b></li>
    </ul>

    <Button OnClick="@ShowDialogLoop">弹窗</Button>
</Block>

<Block Title="模态对话框" Introduction="通过 <code>ShowModal</code> 方法弹出线程阻塞模式的对话框">
    <p>功能介绍</p>
    <ul class="ul-demo">
        <li>点击按钮弹出模态弹窗</li>
        <li>更改模态弹窗内数值点击 <code>确认</code> 按钮时数值 <b>更新</b></li>
        <li>更改模态弹窗内数值点击 <code>取消</code> 或者 <code>关闭</code> 按钮时数值 <b>不更新</b></li>
        <li>再次点击弹出模态弹窗时,数值保持一致</li>
    </ul>
    <Button @onclick="@OnResultDialogClick">点击打开 Dialog</Button>
    <Logger @ref="Trace" class="mt-3" />
</Block>

<Block Title="实战演练" Introduction="模拟一个邮件应用,弹窗选择收件人后填入下方的收件人框。">
    <p>功能介绍</p>
    <ul class="ul-demo">
        <li>点击按钮弹出模态弹窗</li>
        <li>通过级联传参 <code>BodyContext</code> 传递 <b>10</b> 到弹窗中初始化数据</li>
        <li>选中 <code>Table</code> 组件中的行数据,通过双向绑定对 <code>SelectedRows</code> 数据进行 <b>更新</b></li>
        <li>点击 <b>选中</b> 按钮通过双向绑定对 <code>Emails</code> 数据进行 <b>更新</b></li>
        <li>点击 <code>取消</code> 或者 <code>关闭</code> 按钮时 <code>Emails</code> 值 <b>不更新</b></li>
        <li>再次点击弹出模态弹窗时,组件内行选中状态保持一致</li>
        <li>弹窗中未选择用户时禁止关闭弹窗</li>
    </ul>
    <div class="form-inline">
        <label class="control-label">收件人:</label>
        <div class="input-group flex-fill">
            <BootstrapInput placeholder="请输入 ..." Value="@InputValue"></BootstrapInput>
            <div class="input-group-append">
                <Button Icon="fa fa-vcard-o" OnClick="@OnEmailButtonClick"></Button>
            </div>
        </div>
    </div>
</Block>

<AttributeTable Items="@GetAttributes()" Title="DialogOption 属性" />
// Copyright (c) Argo Zhang (argo@163.com). All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
// Website: https://www.blazor.zone or https://argozhang.github.io/

using BootstrapBlazor.Components;
using BootstrapBlazor.Shared.Common;
using BootstrapBlazor.Shared.Pages.Components;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks;

namespace BootstrapBlazor.Shared.Pages
{
    /// <summary>
    /// 弹窗组件示例代码
    /// </summary>
    public sealed partial class Dialogs
    {
        [NotNull]
        private Logger? Trace { get; set; }

        /// <summary>
        /// 获得 弹窗注入服务
        /// </summary>
        [Inject]
        [NotNull]
        private DialogService? DialogService { get; set; }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private Task OnClick() => DialogService.Show(new DialogOption()
        {
            Title = "我是服务创建的弹出框",
            BodyTemplate = BootstrapDynamicComponent.CreateComponent<Button>(new[]
            {
                new KeyValuePair<string, object?>(nameof(Button.ChildContent), new RenderFragment(builder => builder.AddContent(0, "我是服务创建的按钮")))
            })
            .Render()
        });

        private async Task Show()
        {
            var option = new DialogOption()
            {
                Title = "利用代码关闭弹出框",
            };
            option.BodyTemplate = BootstrapDynamicComponent.CreateComponent<Button>(new[]
            {
                new KeyValuePair<string, object?>(nameof(Button.Text), "点击关闭弹窗"),
                new KeyValuePair<string, object?>(nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, async () => await option.Dialog.Close()))
            }).Render();
            await DialogService.Show(option);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private Task OnClickCounter() => DialogService.Show(new DialogOption()
        {
            Title = "自带的 Counter 组件",
            Component = BootstrapDynamicComponent.CreateComponent<Counter>()
        });

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private Task OnClickParameter() => DialogService.Show(new DialogOption()
        {
            Title = "自带的 Counter 组件",
            BodyContext = "我是传参",
            BodyTemplate = builder =>
            {
                var index = 0;
                builder.OpenComponent<DemoComponent>(index++);
                builder.CloseComponent();
            }
        });

        private int DataPrimaryId { get; set; }

        private async Task OnClickShowDataById()
        {
            var op = new DialogOption()
            {
                Title = "数据查询窗口",
                ShowFooter = false,
                BodyContext = DataPrimaryId
            };
            op.BodyTemplate = BootstrapDynamicComponent.CreateComponent<DataDialogComponent>(new KeyValuePair<string, object?>[]
            {
                new(nameof(DataDialogComponent.OnClose), new Action(async () => await op.Dialog.Close()))
            }).Render();

            await DialogService.Show(op);
        }

        private int DemoValue1 { get; set; } = 1;
        private async Task OnResultDialogClick()
        {
            var result = await DialogService.ShowModal<ResultDialogDemo>(new ResultDialogOption()
            {
                Title = "带返回值模态弹出框",
                ComponentParamters = new KeyValuePair<string, object?>[]
                {
                    new(nameof(ResultDialogDemo.Value), DemoValue1),
                    new(nameof(ResultDialogDemo.ValueChanged), EventCallback.Factory.Create<int>(this, v => DemoValue1 = v))
                }
            });

            Trace.Log($"弹窗返回值为: {result} 组件返回值为: {DemoValue1}");
        }

        private string? InputValue { get; set; }
        private IEnumerable<string> Emails { get; set; } = Array.Empty<string>();

        private async Task OnEmailButtonClick()
        {
            var result = await DialogService.ShowModal<ResultDialogDemo2>(new ResultDialogOption()
            {
                Title = "选择收件人",
                BodyContext = new ResultDialogDemo2.FooContext() { Count = 10, Emails = InputValue },
                ButtonYesText = "选择",
                ButtonYesIcon = "fa fa-search",
                ComponentParamters = new KeyValuePair<string, object?>[]
                {
                    // 用于初始化已选择的用户邮件
                    new(nameof(ResultDialogDemo2.Emails), Emails),
                    new(nameof(ResultDialogDemo2.EmailsChanged), EventCallback.Factory.Create<IEnumerable<string>>(this, v => Emails = v))
                }
            });

            if (result == DialogResult.Yes)
            {
                InputValue = string.Join(";", Emails);
            }
        }

        private async Task ShowDialogLoop()
        {
            await DialogService.Show(new DialogOption()
            {
                Title = $"弹窗 {DateTime.Now}",
                Component = BootstrapDynamicComponent.CreateComponent<DialogDemo>()
            });
        }

        /// <summary>
        /// 获得属性方法
        /// </summary>
        /// <returns></returns>
        private static IEnumerable<AttributeItem> GetAttributes()
        {
            return new AttributeItem[]
            {
                new AttributeItem() {
                    Name = "Component",
                    Description = "对话框 Body 中引用的组件的参数",
                    Type = "DynamicComponent",
                    ValueList = " — ",
                    DefaultValue = " — "
                },
                new AttributeItem() {
                    Name = "BodyContext",
                    Description = "弹窗传参",
                    Type = "object",
                    ValueList = " — ",
                    DefaultValue = " — "
                },
                new AttributeItem() {
                    Name = "BodyTemplate",
                    Description = "模态主体 ModalBody 组件",
                    Type = "RenderFragment",
                    ValueList = " — ",
                    DefaultValue = " — "
                },
                new AttributeItem() {
                    Name = "FooterTemplate",
                    Description = "模态底部 ModalFooter 组件",
                    Type = "RenderFragment",
                    ValueList = " — ",
                    DefaultValue = " — "
                },
                new AttributeItem() {
                    Name = "IsCentered",
                    Description = "是否垂直居中",
                    Type = "boolean",
                    ValueList = "true|false",
                    DefaultValue = "true"
                },
                new AttributeItem() {
                    Name = "IsScrolling",
                    Description = "是否弹窗正文超长时滚动",
                    Type = "boolean",
                    ValueList = "true|false",
                    DefaultValue = "false"
                },
                new AttributeItem() {
                    Name = "ShowCloseButton",
                    Description = "是否显示关闭按钮",
                    Type = "boolean",
                    ValueList = "true|false",
                    DefaultValue = "true"
                },
                new AttributeItem() {
                    Name = "ShowFooter",
                    Description = "是否显示 Footer",
                    Type = "boolean",
                    ValueList = "true|false",
                    DefaultValue = "true"
                },
                new AttributeItem() {
                    Name = "Size",
                    Description = "尺寸",
                    Type = "Size",
                    ValueList = "None / ExtraSmall / Small / Medium / Large / ExtraLarge",
                    DefaultValue = "Large"
                },
                new AttributeItem() {
                    Name = "Title",
                    Description = "弹窗标题",
                    Type = "string",
                    ValueList = " — ",
                    DefaultValue = " 未设置 "
                },
            };
        }
    }
}

B 站相关视频链接

[传送门]

交流群

QQ群:BootstrapAdmin & Blazor 795206915(满) 675147445 欢迎加群讨论
Themes
Bootstrap
Ant Design (完善中)
Bluma (完善中)
LayUI (完善中)
An error has occurred. This application may no longer respond until reloaded. Reload