在项目开发中有一定的团队用到了Nuget、Coding;但是这用起来还是不太方方便,在Winform中呢,我们可以把一个人的项目当作一个类库项目,因为它生成的是一个dll文件,也就是单一文件,拥有了它,也就是拥有了项目。

类库项目简介

类库项目编译为.dll 程序集,在其他项目中添加对类库项目的引用,就可以访问它的内容(这可以是同一个解决方案的一部分,但这不是必须的)。这将扩展对象提供的封装性,因为类库可以进行修改和更新,而不会影响使用它们的其他项目。这意味着,您可以方便地升级类提供的服务(这会影响多个用户应用程序)。

所以,我们只要引用了它,也就可以在我们的主程序中进行使用项目小组成员的窗体了,那么我们还要手动去引用吗?类库下图,那太扯淡了!

如果你需要显示里面的窗体,你就可以这样,但是,我们要的是动态加载,那我们就不能通过这种方式了。

ClassLibrary1.Form1 from = new ClassLibrary1.Form1();
from.Show();

所以我们就可以通过反射它们,读取我们项目中的dll文件,这样就达到了目的,当然你可以做一个这样的管理界面,也就是窗体名称和dll文件路径的一个数据表,你就可以去读取数据库,去反射响应的dll了,这是非常有意思的事情,下面我就贴出代码,并一一讲解。

private ArrayList fromtypes = new ArrayList();
private ArrayList formObjects = new ArrayList();
private void Form1_Load(object sender, EventArgs e)
{
Assembly assembly = null;
string windowsPath = Path.Combine(Application.StartupPath, "ModulesDll");
foreach (string DllFile in Directory.GetFiles(windowsPath,"*.dll"))
{
assembly = Assembly.LoadFile(DllFile);
Type[] types = assembly.GetTypes();
foreach (Type typeObj in types)
{
if (typeObj.BaseType == typeof(Form))
{
this.fromtypes.Add(typeObj);
ToolStripItem item = this.menuStrip1.Items.Add(typeObj.FullName.ToString());
item.Click += new EventHandler(menuItemNewItem_Click);
}
}
}
}

首秀我们创建了集合来保存一些表单的类型和对象,在窗体加载的时候我们创建了反射类,然后我们还获取了dll的文件夹位置,就这样我们在其中进行了读取,获取了程序集的内容以及类型,然后再一一匹配,加入了我们的控件项中,然后给这个按钮添加了一个委托。

 private void menuItemNewItem_Click(object sender, EventArgs e)
{
ToolStripMenuItem item = (ToolStripMenuItem)sender;
Type t = (Type)(this.fromtypes[Convert.ToInt32(item.Tag)]);
Object obj = Activator.CreateInstance(t);
this.formObjects.Add(obj);
t.InvokeMember("Text", BindingFlags.SetProperty, null, obj, new object[] { t.FullName + " 窗体"});
t.InvokeMember("Show", BindingFlags.InvokeMethod, null, obj, new object[] { });
ToolStripMenuItem tsmi = new ToolStripMenuItem();
tsmi.Click += new EventHandler(menuItemWindow_Click);
}

在委托中获取了源对象,也就是本身,然后通过把这个本身转换成了控件需要的项,获取了其中深度是为了匹配它的类型,我们还通过了Activator类创建了Form的实例,在集合中添加了该对象,再之后,通过了InvokeMember给这个对象的属性添加了一些值,最后我们再给这个对象添加一个Click,如以下定义

private void menuItemWindow_Click(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
((Form)(this.formObjects[item.Index - ])).Activate();
}

通过 Activate 方法来激活窗体,如果你是mdi窗体,你需要 InvokeMember 进入父窗体,如以下定义

 t.InvokeMember("MdiParent", BindingFlags.SetProperty, null, obj, new object[] { this });

你可以创建一个表来存储这些相关数据,我这里也不多说那些字段了,自己体会吧,大概就是以下定义

create table ProjectModules
(
id int , DllPath nvarchar, FromName varchar, isDisplay bit
)

WinForm加载外部类库项目的集成开发模式的更多相关文章

  1. 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

    [源码下载] 背水一战 Windows 10 (11) - 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件 作者 ...

  2. 资源: CustomResource, ResourceDictionary, 加载外部的 ResourceDictionary 文件

    CustomResource ResourceDictionary 加载外部的 ResourceDictionary 文件 示例1.演示“CustomResource”相关知识点Resource/Cu ...

  3. Vue 加载外部js文件

    Vue.js  加载外部js文件 在项目内新建一个config.js //变量的定义 export var config = { baseurl:'http://172.16.114.5:8088/M ...

  4. iframe 加载外部资源,显示隐藏loading,onload失效

    在项目中使用iframe 来加载外部资源,需要在iframe请求外部资源的时候,需要显示一个loading,在加载完成后,将这个loading隐藏掉,刚开始看到W3C中 iframe有一个 onloa ...

  5. UNITY_资源路径与加载外部文件

    UNITY_资源路径与加载外部文件 https://www.tuicool.com/articles/qMNnmm6https://blog.csdn.net/appppppen/article/de ...

  6. Silverlight实用窍门系列:2.Silverlight动态加载外部XML指定地址的WebService---(动态加载外部XML文件中指定的WebService地址)【附带实例源码】

    接上节所讲的,Silverlight可以加载外部的XML文件里面的内容,那么我们可不可以在外部XML里面配置一个WebService地址,并且以此加载这个地址来动态加载WebService呢?这样子就 ...

  7. 【转】C# winform 加载网页 模拟键盘输入自动接入访问网络

    [转]C# winform 加载网页 模拟键盘输入自动接入访问网络 声明: 本文原创,首发于博客园 http://www.cnblogs.com/EasyInvoice/p/6070563.html  ...

  8. Windows Phone 8加载外部动态链接库DLL(非安装包内的)

    Windows Phone 8加载外部动态链接库DLL(非安装包内的) 在<动态加载与插件化>中大概介绍了下,wp8加载非安装包的下动态链接库,这次详细梳理下. 加载外部DLL主要的原理: ...

  9. Android 插件化开发(二):加载外部Dex文件

    在学习Java反射的技术后,我们可以开始更深一步的探究插件化开发了.首先先讲一下Android App的打包流程,然后我们通过一个简单的例子 —— 实现插件化加载外部Dex来完成初级的插件化开发的探索 ...

随机推荐

  1. DDGScreenShot—截取图片的任意部分

    写在前面 DDGScreenShot 库提供了截取任意图片的功能, 支持手势截图,当然,输入任意的区域也可以,下面看看具体的代码 代码如下: 方法封装 /** ** 用手势截图(截取图片的任意部分) ...

  2. 基于ThreadPoolExecutor,自定义线程池简单实现

    一.线程池作用 在上一篇随笔中有提到多线程具有同一时刻处理多个任务的特点,即并行工作,因此多线程的用途非常广泛,特别在性能优化上显得尤为重要.然而,多线程处理消耗的时间包括创建线程时间T1.工作时间T ...

  3. 算法训练 2的次幂表示(蓝桥杯C++写法)

    问题描述 任何一个正整数都可以用2进制表示,例如:137的2进制表示为10001001. 将这种2进制表示写成2的次幂的和的形式,令次幂高的排在前面,可得到如下表达式:137=2^7+2^3+2^0 ...

  4. 团队项目第二阶段个人进展——Day3

    一.昨天工作总结 冲刺第三天,基本完成发布页面的布局 二.遇到的问题 添加照片的样式会随照片增加而改变 三.今日工作规划 分析要封装的数据有哪些,数据如何传到后端服务器中

  5. 高通调试 SPI 屏的 bug

    1. spi调试问题: 问题描述: spi屏幕lk启动的时候正常出现小企鹅,到kernel启动的过程黑屏并且花屏才到开机动画: 2. 黑屏的三个阶段: 参照:黑屏分析 分析开机过程黑屏,首先需要定位黑 ...

  6. Diffie-Hellman密钥协商算法

    一.概述 Diffie-Hellman密钥协商算法主要解决秘钥配送问题,本身并非用来加密用的:该算法其背后有对应数学理论做支撑,简单来讲就是构造一个复杂的计算难题,使得对该问题的求解在现实的时间内无法 ...

  7. linux几种定时函数的使用

    Linux定时函数介绍: 在程序开发过程中,我们时不时要用到一些定时器,通常如果时间精度要求不高,可以使用sleep,uslepp函数让进程睡眠一段时间来实现定时, 前者单位为秒(s),后者为微妙(u ...

  8. SSM-MyBatis-07:Mybatis中SqlSession的insert和delete底层到底做了什么

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 先点进去看一下insert方法 用ctrl加鼠标左键点进去看 发现是一个接口SqlSession的方法,没有实 ...

  9. 探讨SELECT语句的元数据&amp;动态取样&amp;读一致性导致的一致性读和递归操作

    前几天,论坛上的同行在讨论SELECT语句的元数据,动态取样和读一致性导致的一致性读和递归问题,今天有时间,就试着进行了测试,本人测试环境如下: win7_64+Oracle11.2.0.4_64 那 ...

  10. 远程备份binlog服务

    Ⅰ.bonlog server介绍 对于binlog的备份,之前文章里说的是有从机,一般不备份,那现在人家就是 要备份嘛,怎么办嘛, 写个脚本每天夜里去把前一天产生的binlog拷贝出来可以不? 行啊 ...