Winform使用Webview2创建界面,配置Router管理界面窗体界面
- 往期目录
- Router的使用
-
- 使用方法
- 配置Router方法
- [RouterInfo 配置](#RouterInfo 配置)
- Routers.cs代码文件和使用场景模拟
- 往期目录
往期目录
Router的使用
便于窗口管理,使用统一的路由配置
使用方法
csharp
//普通使用
Form form= Routers.Utils.Push('Demo1');
//对 form 做一些其他操作
csharp
//定制使用
//根据配置路由获取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
变量。设置变量
csharp
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代码
csharp
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代码
csharp
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布局,设置
Dock
为Top
。 - 在MainForm的构造函数中,通过代码创建button,并和Routers配置关联。
csharp
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);
});
}