五.Winform使用Webview2创建界面,配置Router管理界面窗体界面

Winform使用Webview2创建界面,配置Router管理界面窗体界面

  • 往期目录
  • Router的使用
    • 使用方法
    • 配置Router方法
    • RouterInfo 配置
  • Routers.cs代码文件和使用场景模拟
    • Routers.cs代码
    • RouterUtils.cs代码
    • 使用场景
      • 1.创建窗体程序
      • 2.在MainForm窗体上添加`FlowLayoutPanel`用来显示按钮
  • 往期目录

往期目录

专栏目录

Router的使用

便于窗口管理,使用统一的路由配置

使用方法

    //普通使用
   Form form= Routers.Utils.Push('Demo1');
   //对 form 做一些其他操作

    //定制使用
    //根据配置路由获取form
    Form form = Routers.Utils.CreateForm(routerInfo);
    //设置参数或添加事件
    form.MdiParent = _mainForm;
    form.WindowState = FormWindowState.Maximized;
    form.MinimizeBox = false;
    form.MaximizeBox = false;

    form.Load+=(object sender,EventArgs:e)=>{

    }

    ....
    //根据路由配置显示窗口
    Routers.Utils.ShowForm(form,routerInfo);

配置Router方法

Router/Routers.cs中 找到List<RouterInfo> List 变量。设置变量

public static List<RouterInfo> List = new List<RouterInfo>() {
   //创建RouterInfo 对象
   new RouterInfo()
   {
       //窗口Name 必须唯一
       Name="Demo1",
       //窗口显示文字
       Text="Webview2 初始基本HTML展示,回车导航",
       
       //是否时多文档窗口
       //需要提前为父级多文档窗口设置 MDI
       //TIP 多文档窗口 和 模态窗口不能同时设置
       IsMdiContainer=true ,

       //模态窗口 
       IsShowDialog=true,
 
       //一个描述字段,通常不会使用
       Remake="描述字段",     

       //要显示的Form对象
       // FormAction方法和Form变量同时设置 会优先使用FormAction
       Form=new Demo1(), //Form 每次关闭只会隐藏窗口,并不会销毁
       FormAction=()=>new Demo1(), //FormAction每次打开都是一个新的窗口

       //Form 参数,会存储到Form 的 Tag变量中 
       Params=( new Dictionary<string, object>(){
           { "test1","test2"}
       }),

       //Load事件 ,在窗体加载时触发。不会影响原事件
       Load=(object sender,EventArgs e) =>
       {
           MessageBox.Show("Demo1窗体加载了!");
       },
       
    },

    new RouterInfo(){
        .....
    },
    ....
};

RouterInfo 配置

参数 类型 含义 允许空 参数 返回值
Name String 窗口Name 必须唯一 N - -
Text String 窗口显示文字 Y - -
Remake String 描述字段 Y - -
Params Dictionary<string, object> 窗体参数 Y - -
Form Form 要显示的Form对象 Form|FormAction必须具备一个 - -
FormAction FormAction()=>{} 要显示的Form对象,优先级高于Form参数 Form|FormAction必须具备一个 - Form
Load EventHandler 窗体加载事件,在窗体加载时触发。不会影响原事件 Y - void

Routers.cs代码文件和使用场景模拟

创建 Router文件夹,下面创建Routers.cs和RouterUtils.cs文件

Routers.cs代码

?using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;

namespace WinformWebview2.Router
{
    public class Routers
    {  
    	//配置相关窗口信息,假如有一下窗口 Demo1 Demo2 Demo3_1 Demo3_2
        public static List<RouterInfo> List = new List<RouterInfo>() {
           new RouterInfo()
           {
               Name="Demo1",
               Text="Webview2 初始基本HTML展示,回车导航",
               Form=new Demo1(),
               Params=( new Dictionary<string, object>(){
                   { "test1","test2"}
               }),
               Load=(object sender,EventArgs e) =>
               {
                   MessageBox.Show("Demo1窗体加载了!");
               },
               IsShowDialog=true, //模态窗口 
            },
            new RouterInfo()
            {
               Name="Demo2",
               Text="和WebView2 中HTML 和C#之间通信",
               //Form=new Demo2(),
               FormAction=()=>new Demo2(),
               
               //是否时多文档窗口
               //需要提前为父级多文档窗口设置 MDI
               IsMdiContainer=true ,

               //IsShowDialog=true, //模态窗口 

               //窗口加载
               Load=(object sender,EventArgs e) =>
               {
                   MessageBox.Show("Demo2窗体加载了!");
               },

            },
            new RouterInfo()
            {
               Name="Demo3_1",
               Text="Demo3_1",
               Form=new Demo3_1(),
            },
            new RouterInfo()
            {
               Name="Demo3_2",
               Text="Demo3_2",
               Form=new Demo3_1(),
            },
        };

        public static RouterUtils Utils = new RouterUtils(List);

    }
}

通过配置进行集中管理窗体界面,后通过调用可以实现页面跳转。

RouterUtils.cs代码

using System.Collections.Generic;
using System.Windows.Forms;

namespace WinformWebview2.Router
{

    public class RouterUtils
    {
        /// <summary>
        /// 保存路由
        /// </summary>
        public List<RouterInfo> RouteList;
        public Dictionary<string, RouterInfo> RouteMap = new Dictionary<string, RouterInfo>();

        public RouterUtils(List<RouterInfo> _RouteList)
        {
            this.RouteList = _RouteList;

            ///创建 key-value 便于快速查找
            _RouteList.ForEach((RouterInfo _route) =>
            {
                this.RouteMap.Add(_route.Name, _route);
            });
        }
        /// <summary>
        /// 获取路由
        /// </summary>
        /// <param name="RouteName">路由唯一标识</param>
        /// <returns></returns>
        public RouterInfo GetRouterInfo(string RouteName)
        {
            if (this.RouteMap == null || this.RouteMap.Count <= 0)
            {
                return null;
            }
            return this.RouteMap[RouteName];
        }

        #region 获取窗口

        public Form GetForm(RouterInfo routerInfo)
        {
            if (routerInfo.FormAction != null)
            {
                return routerInfo.FormAction();
            }
            return routerInfo.Form;
        }

        #endregion

        #region 路由跳转
        /// <summary>
        /// 路由跳转
        /// </summary>
        public Form Push(String RouteName)
        {
            return this.Push(RouteName, null);
        }
        public Form Push(String RouteName, Dictionary<string, object> Params)
        {
            RouterInfo routerInfo = this.GetRouterInfo(RouteName);
            return this.Push(routerInfo, Params);
        }
        public Form Push(RouterInfo routerInfo)
        {
            return this.Push(routerInfo, null);
        }
        public Form Push(RouterInfo routerInfo, Dictionary<string, object> Params)
        {
            Form form = this.CreateForm(routerInfo, Params);
            this.ShowForm(form, routerInfo);
            return form;
        }

        #endregion

        #region 创建窗口,设置相关参数
        public Form CreateForm(RouterInfo routerInfo)
        {
            return this.CreateForm(routerInfo, null);
        }
        public Form CreateForm(RouterInfo routerInfo, Dictionary<string, object> Params)
        {
            Form form = this.GetForm(routerInfo);
            form.Text = routerInfo.Text;
            form.Name = routerInfo.Name;
            ///将form的params存在Tag中  
            form.Tag = Utils.Utils.MergeDic(Params, routerInfo.Params);

            if (routerInfo.Load != null)
            {


                form.Load += (object sender, EventArgs e) =>
                {
                    routerInfo.Load(sender, e);
                    if (routerInfo.LoadingAfter != null)
                    {
                        form = routerInfo.LoadingAfter(sender, e, form);
                    }
                };
            }

            form.FormClosing += (object sender, FormClosingEventArgs e) =>
            {
                if (routerInfo.FormAction == null)
                {
                    form.Hide();
                    e.Cancel = true;
                }
            };
            return form;
        }
        #endregion

        #region 显示窗口
        /// <summary>
        /// 显示窗口
        /// </summary>
        /// <param name="form"></param>
        /// <param name="isDialog"></param>
        public void ShowForm(Form form, RouterInfo routerInfo)
        {
            this.ShowForm(form, routerInfo.IsShowDialog);
        }
        /// <summary>
        /// 显示窗口
        /// </summary>
        /// <param name="form"></param>
        /// <param name="isDialog"></param>
        public void ShowForm(Form form, bool isDialog)
        {
            try {
                if (isDialog)
                {
                    form.ShowDialog();
                    return;
                }
                form.Show();
            } catch(Exception exception) {
                MessageBox.Show(exception.Message.ToString());
                //非顶级窗体不能显示为模式对话框。在调用 showDialog 之前应从所有父窗体中移除该窗体。
                //出现以上错误说明:不能同时设置IsMdiContainer和IsShowDialog

            }
        }

        #endregion



    }

    public class RouterInfo
    {
        /// <summary>
        /// 路由Name 唯一标识
        /// </summary>
        public string Name;

        /// <summary>
        /// 路由地址相关窗口名称
        /// </summary>
        public string Text;

        /// <summary>
        /// 路由参数
        /// </summary>
        public Dictionary<string, object> Params;


        /// <summary>
        /// 路由对于的窗口
        /// </summary>
        public Form Form;
        /// <summary>
        ///  路由对于的窗口 通过函数返回form ,这样在每次调用都可以创建一个新窗口
        /// </summary>
        /// <returns>Form</returns>
        public delegate Form FormActionHandler();
        public FormActionHandler FormAction;

        /// <summary>
        /// 是否多文档界面 TIP 需要自行进行关联
        /// 需要先设置多文档界面的父级窗口
        /// </summary>
        public bool IsMdiContainer;

        / <summary>
        / 多文档界面的父级窗口
        / </summary>
        //public Form MdiParent;


        /// <summary>
        /// 是否模态显示
        /// </summary>
        public bool IsShowDialog;


        /// <summary>
        /// 描述
        /// </summary>
        public String Remake;

        /// <summary>
        /// 窗体的加载事件
        /// </summary>
        /// <returns></returns>
        public EventHandler Load;

        /// <summary>
        /// 在初始化完成后触发事件
        /// </summary>
        /// <param name="form"></param>
        /// <returns></returns>
        public delegate Form LoadingAfterAfterHandler(object sender, EventArgs e, Form form);
        public LoadingAfterAfterHandler LoadingAfter;

       

    }
}

使用场景

1.创建窗体程序

创建窗体Demo3_1,创建窗体Demo3_2

2.在MainForm窗体上添加FlowLayoutPanel用来显示按钮

  • 将之前的按钮删除掉,使用FlowLayoutPanel布局,设置DockTop
  • 在MainForm的构造函数中,通过代码创建button,并和Routers配置关联。
        public MainForm()
        {
            InitializeComponent();
            //创建按钮和按钮事件并添加到FlowLayoutPanel控件上
            CreateButton();

        }
        /// <summary>
        /// 根据路由配置加载按钮
        /// </summary>
        public void CreateButton()
        {
            //设置MainForm多文档窗口,如果需要的话,不需要则注释
            Form _mainForm = this;
            
            //获取路由配置并遍历
            Routers.List.ForEach(routerInfo =>
            {
            	//创建按钮
                Button button = new Button();
                button.Text = routerInfo.Text;
                button.Name = routerInfo.Name;
                button.Tag = routerInfo.Params;
                button.AutoSize = true;
                
                //设置按钮点击事件 点击打开窗口
                button.Click += (object sender, EventArgs e) =>
                {
                    //根据情况判断要不要设置 多文档窗口
                    if (routerInfo.IsMdiContainer)
                    {
                    	//多文档窗口我们需要获取到对于的form对象
                        Form form = Routers.Utils.CreateForm(routerInfo);
                        //设置Form窗口为多文档
                        _mainForm.IsMdiContainer = true;
                        form.MdiParent = _mainForm;                        
                        //显示窗口 
                        Routers.Utils.ShowForm(form,routerInfo);
                    }
                    else { 
                        Routers.Utils.Push(((Control)sender).Name);
                    }
                };
				
				//添加到FlowLayoutPanel控件上
                flyFormPanel.Controls.Add(button);
            });
        }

往期目录

专栏目录