在Winform界面中实现对多文档窗体的参数传值
在Winform界面中窗体我们一般使用多文档进行展示,也就是类似一般的选项卡的方式可以加载多个窗体界面。一般来说,我们如果打开新的窗体,给窗体传递参数是很容易的事情,但是在框架层面,一般的窗体是通过动态创建的,一般传入窗体的类型,在多文档集合里面判断,如果存在则激活,如果不存在则创建的方式,所以我们传递参数会碰到一些问题。本文即使介绍如何在这种方式下,给窗体对象传递参数,从而实现相应的数据处理功能。
不管是主体界面中,左侧包含树形列表,还是顶部包含工具栏的情况,都可能涉及打开窗体的时候,传递一些初始化参数,方便窗体的更新显示的情况,这种的处理相对直接传值的方式需要复杂一点,我们可以通过接口、事件的方式进行处理,下面我来介绍一下整个实现的方式。
1、多文档窗体的构建或者激活
在我的Winform开发框架里面,我们加载多文档窗体的时候,都是统一采用一种方式来进行构建不存在或者激活已有窗体的,代码如下所示。
private void tool_Purchase_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
ChildWinManagement.LoadMdiForm(this, typeof(FrmPurchase));
} private void tool_TakeOut_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
ChildWinManagement.LoadMdiForm(this, typeof(FrmTakeOut));
} private void tool_StockSearch_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
ChildWinManagement.LoadMdiForm(this, typeof(FrmStockSearch));
}
而这个LoadMdiForm的函数,主要判断多文档集合里面是否有对应的对象,没有这创建,有则激活显示即可,代码如下所示。
/// <summary>
/// 唯一加载某个类型的窗体,如果存在则显示,否则创建。
/// </summary>
/// <param name="mainDialog">主窗体对象</param>
/// <param name="formType">待显示的窗体类型</param>
/// <param name="json">传递的参数内容,自定义Json格式</param>
/// <returns></returns>
public static Form LoadMdiForm(Form mainDialog, Type formType, string json)
{
bool bFound = false;
Form tableForm = null;
foreach (Form form in mainDialog.MdiChildren)
{
if (form.GetType() == formType)
{
bFound = true;
tableForm = form;
break;
}
}
if (!bFound)
{
tableForm = (Form) Activator.CreateInstance(formType);
tableForm.MdiParent = mainDialog;
tableForm.Show();
} tableForm.BringToFront();
tableForm.Activate(); return tableForm;
}
这种方式构建的多文档界面如下所示。

2、多文档窗体传参数的实现处理
首先,为了实现这个方式,我们需要先创建一个接口,是我们窗体界面的基类,实现这个接口,然后在加载的时候,转换为对应的接口处理就可以了,具体接口代码如下所示。
/// <summary>
/// 使用ChildWinManagement辅助类处理多文档加载的窗体,在构建或激活后,触发一个通知窗体的事件,方便传递相关参数到目标窗体。
/// 为了更加通用的处理,传递的参数使用JSON定义格式的字符串。
/// </summary>
public interface ILoadFormActived
{
/// <summary>
/// 窗体激活的事件处理
/// </summary>
/// <param name="json">传递的参数内容,自定义JSON格式</param>
void OnLoadFormActived(string json);
}
这里参数为了通用,我们定义为字符串的JSON内容,方便实现更加强大的参数处理。
修改好这些,我们需要在基类窗体 BaseForm 实现这个增加的接口,如下所示。
/// <summary>
/// 常规界面基类
/// </summary>
public partial class BaseForm : XtraForm, IFunction, ILoadFormActived
实现这个接口很容易,为了更加方便业务窗体(继承自基类窗体BaseForm),我们提供一个事件进行处理,具体代码如下所示。
/// <summary>
/// 常规界面基类
/// </summary>
public partial class BaseForm : DevExpress.XtraEditors.XtraForm, IFunction, ILoadFormActived
{
/// <summary>
/// 定义一个窗体激活后的处理委托类型
/// </summary>
/// <param name="json"></param>
public delegate void FormActiveHandler(string json);
/// <summary>
/// 使用ChildWinManagement辅助类处理多文档加载的窗体,在构建或激活后,触发一个通知窗体的事件,方便传递相关参数到目标窗体。
/// 为了更加通用的处理,传递的参数使用JSON定义格式的字符串。
/// </summary>
public event FormActiveHandler LoadFormActived;
同时,我们实现接口,就是直接调用事件就可以了,具体代码如下所示。
/// <summary>
/// 窗体激活的事件处理
/// </summary>
/// <param name="json">传递的参数内容,自定义JSON格式</param>
public virtual void OnLoadFormActived(string json)
{
//默认什么也没做
//如果需要处理传参数,则在这里处理参数Json即可
if (LoadFormActived != null)
{
LoadFormActived(json);
}
}
这样我们就完成了基类窗体的处理了,前面我们介绍了动态构建加载窗体的时候,是使用了LoadMdiForm的函数,既然我们的接口实现了上面的ILoadFormActived接口,那么我们动态创建或者激活窗体的时候,那么就使用这个接口进行处理一下,以便实现对应事件的处理操作了。因此我们的窗体加载函数修改代码,如下所示。
/// <summary>
/// 唯一加载某个类型的窗体,如果存在则显示,否则创建。
/// </summary>
/// <param name="mainDialog">主窗体对象</param>
/// <param name="formType">待显示的窗体类型</param>
/// <param name="json">传递的参数内容,自定义Json格式</param>
/// <returns></returns>
public static Form LoadMdiForm(Form mainDialog, Type formType, string json)
{
bool bFound = false;
Form tableForm = null;
foreach (Form form in mainDialog.MdiChildren)
{
if (form.GetType() == formType)
{
bFound = true;
tableForm = form;
break;
}
}
if (!bFound)
{
tableForm = (Form) Activator.CreateInstance(formType);
tableForm.MdiParent = mainDialog;
tableForm.Show();
} //窗体激活的时候,传递对应的参数信息
ILoadFormActived formActived = tableForm as ILoadFormActived;
if (formActived != null)
{
formActived.OnLoadFormActived(json);
} tableForm.BringToFront();
tableForm.Activate(); return tableForm;
}
还记得我们前面打开一个多文档窗体的代码,就是利用这个接口进行创建或者激活指定类型的窗体的,如下所示。
ChildWinManagement.LoadMdiForm(this, typeof(FrmItemDetail));
那么我们增加了新的函数参数Json后,我们如果需要传递一个指定的参数给对应的窗体,那么就修改下调用即可。例如下面,为了测试,我传入一个动态构建的类信息,然后转换为Json字符串信息给接收窗体,并进行加载窗体。
//使用自定义参数调用
var obj = new { ItemNo = "", ItemName = "测试名称" };
var param = JsonConvert.SerializeObject(obj, Formatting.Indented); ChildWinManagement.LoadMdiForm(this, typeof(FrmItemDetail), param);
前面我们介绍了基类窗体,已经实现定义了一个事件,并对这些通知的接口进行处理,具体如下所示。

那么我们前面加载的 FrmItemDetail 需要做哪些工作呢,就是实现对事件的处理即可,如下所示。

这样我们就能够通过实现对应的事件,把整个通知事件的处理处理完毕了,我们来看看最终的界面效果,如下所示,接收到的窗体事件后,会弹出一个提示对话框在右下角了。

当然实际上我们可以做的更多,如可以传递一些具体的信息,让它在界面上进行显示。
如其中一个客户基于我的Winform开发框架基础上进行的参数传递案例界面如下所示。

本文只是对其中在框架层面对不同多文档窗体的传值进行的一个研究探索和实现,其中的理念是基于常用的接口和事件驱动的方式进行处理,以期达到方便、高效的目的,如果您有更好的建议,也希望多多交流。
在Winform界面中实现对多文档窗体的参数传值的更多相关文章
- Winform开发框架中的内容及文档管理模块功能介绍
在开发项目的时候,我们有一些场景需要编辑一些HTML文档,作为内容发布系统的一部分,有时候也需要对一些文档如WORD文档进行编辑管理,这样需要我们对这些内容及文档进行合适的管理.本文主要介绍在WInf ...
- 如何在ASP.NET Core 中快速构建PDF文档
比如我们需要ASP.NET Core 中需要通过PDF来进行某些简单的报表开发,随着这并不难,但还是会手忙脚乱的去搜索一些资料,那么恭喜您,这篇帖子会帮助到您,我们就不会再去浪费一些宝贵的时间. 在本 ...
- Springboot中整合knife4j接口文档
在项目开发过程中,web项目的前后端分离开发,APP开发,需要由前端后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发. 什么是knife4j 简单说knife4j就swagge ...
- 在我的电脑中删除wps云文档图标
在我的电脑中删除wps云文档图标 右键点击win10左下角选择运行,输入regedit打开注册表后,找到以下注册表路径: HKEY_CURRENT_USER\Software\Microsoft\Wi ...
- Elasticsearch中最重要的文档CRUD要牢记
Elasticsearch文档CRUD要牢记 转载参考:https://juejin.im/post/5ddbf298e51d4523053c42e7 在Elasticsearch中,文档(docum ...
- MDI-多文档窗体
1.IsMdicontainer属性设置是否为多文档窗体 this.IsMdiContainer = true; 2.MdiParent属性设置为父窗体 Frm_Child frm = new Frm ...
- Winform界面中主从表编辑界面的快速处理
在Winform开发中,我们往往除了常规的单表信息录入外,有时候设计到多个主从表的数据显示.编辑等界面,单表的信息一般就是控件和对象实体一一对应,然后调用API保存即可,主从表就需要另外特殊处理,本随 ...
- Winform界面中实现菜单列表的动态个性化配置管理
在我们一般的应用系统里面,由于系统是面向不同类型的用户,我们所看到的菜单会越来越多,多一点的甚至上百个,但是我们实际工作接触的菜单可能就是那么几个,那么对于这种庞大的菜单体系,寻找起来非常不便.因此对 ...
- Winform界面中实现通用工具栏按钮的事件处理
在一个给客户做的项目中,界面要求修改增加通用工具栏按钮的事件处理,也就是在主界面中放置几个固定的功能操作按钮,打开不同的页面的时候,实现对应页面的功能处理,这种和我标准的界面处理方式有所不同,标准的列 ...
随机推荐
- java提高篇(二)-----理解java的三大特性之继承
在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...
- JavaScript思维导图—DOM基本操作
JavaScript思维导图-来自@王子墨http://julying.com/blog/the-features-of-javascript-language-summary-maps/ DOM基本 ...
- 目前在做的一个web应用程序的前端选型
最近进入了一个新的项目组,要新起一个项目.这个Web项目是一个企业内部使用的系统,主要用来记录.追踪.管理潜在客户的数据.该系统有以下特点: 需要支持IE10及以上版本: 后端采用micro serv ...
- js菜单默认选中
function defaultSelected() { var curr = $("#leftTree li[onclick*='" + $("#content_ifr ...
- WebApi系列~按需序列化字段~Hot
回到目录 起初只是一个想法,一次讨论,一个设想,但相信一定可以实现,具体的事情是这样的,有个对外的API项目,它为一些终端设备提供数据,如手机,平板,PC,当然你也可以说它为很多平台提供数据win32 ...
- 第1讲 Redis部署与基本操作
目录 一.简介 二.安装 1.默认安装位置 2.指定安装位置 3.安装的可执行文件的作用 三.启动与关闭 四.配置文件 五.Redis的数据类型 1. 共计5种类型 2. String(子串类型) 3 ...
- png图片尺寸大小调整
Android 开发中经常遇到各种hdpi,xhdpi,xxhdpi....很多尺寸大小的png图片要求. 网上也有不少工具,今天我又发现一款在线转换大小的网站,用了一下,一个png 114X114 ...
- H5常用代码:适配方案2
前面的通过视口做适配的方案由于安卓低版本原生浏览器的存在,在许多场合不尽如人意,会在低版本安卓上出现,不缩放,手动缩放未禁止的问题. 于是出现了第二种适配方案,既然通过视口缩放可以兼容,那为什么不直接 ...
- Atitit 编程语言常用算法attilax总结
Atitit 编程语言常用算法attilax总结 1. 编译算法分类and 数据操作算法.1 1.1. Tab driver stat 状态转换表格算法1 1.2. Nest case 词法分析 ...
- C#学习系列-String与string的区别
参考:http://www.microsoftvirtualacademy.com/Content/ViewContent.aspx?et=9851&m=9832&ct=31042 如 ...