Blazor无限级Dialog解决方案

设计思路

1.通过DialogContainer组件动态显示
2.使用Dictionary存储所有显示的Dialog
3.使用StateHasChanged强制更新DialogContainer呈现树
4.主要代码如下

DialogOption

public class DialogOption {
    public string Title { get; set; }
    public int Width { get; set; } = 500;
    public int Height { get; set; } = 300;
    public RenderFragment Content { get; set; }
}

DialogContainer

public class DialogContainer : BaseComponent {
    private string previous;//上一个Dialog
    private string current; //当前Dialog
    //存储所有Dialog
    private readonly Dictionary<string, DialogOption> dialogs = new();

    public void Show(DialogOption option) {
        previous = current;
        current = option.Title;
        if (!dialogs.ContainsKey(current)) {
            dialogs[option.Title] = option;
            StateHasChanged();
        }
    }

    public void Close() {
        if (string.IsNullOrWhiteSpace(current))
            return;
        if (dialogs.ContainsKey(current)) {
            dialogs.Remove(current);
            current = previous;
            StateHasChanged();
        }
    }

    protected override void OnInitialized() {
        base.OnInitialized();
        if (DialogService != null) {
            DialogService.Register(this);
        }
    }

    protected override void BuildRenderTree(RenderTreeBuilder builder) {
        foreach (var item in dialogs) {
            var option = item.Value;
            builder.Component<Dialog>(attr =>
            {
                attr.Add(nameof(Dialog.Title), option.Title)
                    .Add(nameof(Dialog.Width), option.Width)
                    .Add(nameof(Dialog.Height), option.Height)
                    .Add(nameof(Dialog.Content), option.Content)
                    .Add(nameof(Dialog.OnClose), Callback(e => Close()));
            });
        }
    }
}

Dialog

public class Dialog : BaseComponent {
    [Parameter] public string Title { get; set; }
    [Parameter] public int Width { get; set; } = 500;
    [Parameter] public int Height { get; set; } = 300;
    [Parameter] public RenderFragment Content { get; set; }
    [Parameter] public EventCallback OnClose { get; set; }

    protected override void BuildRenderTree(RenderTreeBuilder builder) {
        builder.Div(attr => attr.Class("mask"));
        builder.Div(attr =>
        {
            attr.Class("dialog").Style(GetStyle());
            BuildHead(builder);
            BuildContent(builder);
        });
    }

    private void BuildHead(RenderTreeBuilder builder) { }

    private void BuildContent(RenderTreeBuilder builder) { }

    private string GetStyle() {
        return new StyleBuilder()
                .Add("width", $"{Width}px")
                .Add("height", $"{Height}px")
                .Add("margin-top", $"-{Height / 2}px")
                .Add("margin-left", $"-{Width / 2}px")
                .Build();
    }
}

DialogService

public class DialogService {
    private DialogContainer Dialog { get; set; }

    public void Show(DialogOption option) {
        Dialog.Show(option);
    }

    internal void Register(DialogContainer dialog) {
        Dialog = dialog;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值