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;
}
}
posted @   known  阅读(129)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2009-04-30 CSS HACK 兼容列表 Firefox, IE5, IE5.5, IE6, IE7, IE8
点击右上角即可分享
微信分享提示