日期:2014-05-17  浏览次数:20875 次

C#动态加载界面的问题
最近需要写一个管理程序,因为以后可能需要升级不同功能,因此想只写一个框架界面,以后不同功能和界面以dll插件的形式升级。当框架界面启动时检测到目录下有dll时,就通过不同tab页面加载dll中的功能显示出来。这样如何实现呢?如果有简单示例代码就更好了。谢谢各位了

------解决方案--------------------
给你举一个例子。假设你的屏幕有一个菜单树,显示一些用户关心的对象的分类列表,然后在树的旁边有一个大的区域动态加载不同的用户控件,那么你可以在你的保存树的节点的数据库(不管它是关系数据库、文本文件、Excel表,还是什么别的,反正都是数据库)中在每一个节点的名字的旁边另外设计一个叫做“UI Type Name”的字段,来保存用户界面的类型信息。

然后你的树控件捕获到节点被点击以后,可以读取节点所对应的 UI 类型信息,例如
private void treeview_NodeSelected(object sender, EventArgs e)
{
    var typeName = 查询节点对应的UI类型信息(treeview1.SelectedValue);
    var ts = typeName = typeName.Split(',');
    var asm = Assembly.LoadFrom(ts[1]);
    var ctrl = (UserControl)Activator.CreateInstance(asm.GetType(ts[0]));
    Panel1.Controls.Clear();
    Panel1.Controls.Add(ctrl);
}


而假设你的主程序有A、B、C三类数据资料,你还可以进一步为ctrl按需传入数据资料,例如:
void treeview_NodeSelected(object sender, EventArgs e)
{
    var typeName = 查询节点对应的UI类型信息(treeview1.SelectedValue);
    var ts = typeName = typeName.Split(',');
    var asm = Assembly.LoadFrom(ts[1]);
    var ctrl = (UserControl)Activator.CreateInstance(asm.GetType(ts[0]));
    Panel1.Controls.Clear();
    Panel1.Controls.Add(ctrl);
    var ca = ctrl as IRequireDatasA;
    if(ca !=null)
        ca.SetDatas(this.DataA);
    var cb = ctrl as IRequireDatasB;
    if(cb !=null)
        cb.SetDatas(this.DataB);
    var cc = ctrl as IRequireDatasC;
    if(cc !=null)
        vc.SetDatas(this.DataC);
}

根据接口编程,那么你的主程序可以如此这样地捕获 ctrl 的接口,调用其相应的各种方法、属性、事件交互,等等。

这个例子实在是太土了。其实越是简单的设计,越难以举例。一个非常基本的设计知识它越是“土”(而不是那种臃肿的时髦框架),你要理解并且使用它就越需要智慧。