使用反射将表格显示为DLL中的mdichilds [英] Showing forms as mdichilds from a DLL using reflection

查看:74
本文介绍了使用反射将表格显示为DLL中的mdichilds的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我正在尝试制作一个受插件支持的Windows MDI应用程序,但是我的大脑停了下来!我无法建立算法!
首先,我的程序将从位于MDI父应用程序同一目录中的插件目录中读取DLL,我不知道该如何使用接口和类,因为我创建了一个接口设置名称,然后使用该名称在面板上放置按钮,然后使用该SDK创建了一个DLL.现在它可以工作了,但是我想向该DLL中添加表单,当我单击按钮时,这些表单将在我的父应用程序中显示为MDI子级..

我处理过的代码:

SDKLib.cs

Hi all,

I''m trying to make a plugin supported windows MDI application but my brain has stopped! I can''t build the algorithm!
First of all, my program will read DLLs from plugin directory which is located at the same directory of my MDI parent application, I don''t know what I will use for interfaces and classes, for the moment I created an interface which has to set name and I use that name for placing a button on a panel and I created a DLL with that SDK. Now it''s working, but I want to add forms to that DLL and when I click on my button, those forms will appear as MDI child in my parent application..

The code that I worked on:

SDKLib.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
namespace drSDK
{
    public interface IPlugIn
    {
        string name();
                //I HAVE TO DO SMTH HERE (IN MY OPINION)
    }
    public class Plug
    {
        public string pName;
        public string pPath;
        public string pFName;
    }
    public class Kit
    {
        public static List<Plug> getAllPlugIns(string path)
        {
            List<Plug> myPlugs = new List<Plug>();//list
            if (!Directory.Exists(path))
                return myPlugs;//null
            string[] dlls = Directory.GetFiles(path, "*.dll");//arry dlls
             foreach (string dll in dlls)//all dlls in list
            {
                Assembly asm = Assembly.LoadFile(dll);//open as asm
                Type[] tipler = asm.GetTypes();
                foreach (Type tip in tipler)
                {
                    if (tip.GetInterface("IPlugIn") != null)//Thats my SDK!
                    {
                        Plug myP = new Plug();
                        myP.pFName = tip.FullName;
                        myP.pPath = dll;
                        object obj = asm.CreateInstance(tip.FullName);//dll instance 
                        myP.pName = obj.GetType().InvokeMember("name", BindingFlags.InvokeMethod, null, obj, null).ToString(); //name from interface
                        myPlugs.Add(myP);
                    }
                }
            }
            return myPlugs;
        }
        public static object createObject(Plug p)
        {
            Assembly asm = Assembly.LoadFile(p.pPath);
            object obj = asm.CreateInstance(p.pFName);
            return obj;
        }
    }
}



Form1.cs



Form1.cs

using drSDK;
.
.
.
        List<Plug> myList = null;//Plugin list
        private void Form1_Load(object sender, EventArgs e)
        {
            myList = Kit.getAllPlugIns(Application.StartupPath + "//plugins");//plugin directory
            foreach (Plug p in myList)//4 every plug
            {
                Button b = new Button();
                b.Text = p.pName;
                b.Click += new EventHandler(b_Click);
                NavigatorGroupItemContainerPanel1.Controls.Add(b);
            }
        void b_Click(object sender, EventArgs e)
        {
            foreach (Plug p in myList)
            {
                if (p.pName == (sender as Button).Text)//wats clicked
                {
                    run(p);
                }
            }
        }
        void run(Plug p)
        {
            IPlugIn obj = (IPlugIn)Kit.createObject(p);
            .
            . //I HAVE TO DO SMTH HERE (IN MY OPINION)
            .
            .

        }
        void Pencereler(Form pencere)//Do not open again and again
        {
            bool acik = false;
            foreach (Form eleman in this.MdiChildren)
            {
                if (eleman.Text == pencere.Text)
                {
                    acik = true;
                    eleman.Activate();
                }
                if (acik == false)
                {
                    pencere.MdiParent = this;
                    pencere.Show();
                }
            }
        }



尽我所能将obj的形式保存为:



To the best of my recollection obj as form was like:

Form form = obj as Form;if (form != null){    form.MdiParent = this;    form.Show();}



但是我被卡住了!
我是否需要像...这样的类型?



but I am stuck!
Do I have to get type like...

Type formType = Type.GetType(BLABLA_DLL_BLA_FORM);



还是我必须根据DLL包含的形式创建实例?还是我必须遵循哪种方式?我必须为我的DLL SDK添加哪些接口?好的,我将obj作为表单提供,如果表单不是null 设置此容器,请添加新表单的MDI父级并显示它...如果表单已经打开,激活或BringToFront,我可以添加,但是哪种表单呢? "...来自"哪个界面?我是否必须将Form添加到以Form命名的DLL中?或任何名字? (form1 ... form2 ... blaForm ..)是否有示例项目要检查?



Or do I have to Create Instance off the form which DLL includes? Or what kind of way I''ve to follow for doing this? What interfaces do I have to add for my SDK for DLL? Ok, I give my obj as a form and if form is not null set this container, MDI parent of new form and show it... I may add if the form is already opened, Activate it or BringToFront but which form? "...from" which interface? Do I have to add Form to my DLL named by Form? Or any name? (form1...form2...blaForm..) are there any example projects to examine?

推荐答案

首先使用众所周知的子表单进行尝试,您不需要的Kit.完成该工作后,您可以看到应该具有IPlugIn对象的哪些方法,包括从Form继承的方法.那么从CreateInstance替换对象应该相对容易,因为您已经拥有了一个有效的代码体系结构.

顺便说一句,您的Pencereler方法中的第二个if属于foreach之外,而不是内部.
Try it first using a child form that is fully known, one for which you don''t need your Kit. When you have that working, you can see what methods you should require your IPlugIn object to have, including those inherited from Form. Substituting in the object from CreateInstance should be relatively easy then since you will already have a working code architecture.

BTW, the second if in your Pencereler method belongs outside the foreach, not inside.


这篇关于使用反射将表格显示为DLL中的mdichilds的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆