• 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;
        }
    }
    
  • 相关阅读:
    键盘记录器,可截获到 QQ 的password
    《python源代码剖析》笔记 pythonm内存管理机制
    Unity 捕获IronPython脚本错误
    POJ 3020 Antenna Placement 最大匹配
    XCL-Charts画线图(Line Chart)
    android设置背景色为透明
    设计时属性文件
    Windows Mobile基础
    Wince 的CAB安装包
    惠普的 ipaq112 恢复出厂设置
  • 原文地址:https://www.cnblogs.com/known/p/16211670.html
Copyright © 2020-2023  润新知