设计思路
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;
}
}