各位XDJM,我现在已经实现了在主窗体中动态调用DLL子窗体的功能。但是不知道该如何让主窗体能够感知到子窗体中的事件。比如说子窗体的某个事件触发后,主窗体应该响应对应方法或事件。这个应该采用什么方法?

解决方案 »

  1.   

    你需要在dll中建立委托,初始化子窗体的时候,用主窗体的方法去初始化子窗体的委托方法,然后让其在触发某个事件的时候调用此委托来告知主窗体。
      

  2.   

    谢谢,愚翁,能否写一段提示性的代码,我才刚刚开始学C#,我看了MSDN上的例子是采用回调函数,但是它是调用非托管DLL的。
      

  3.   

    我代码如下:
    主窗体代码:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;namespace CallDll
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private object DllInvoke(string mDllFileName, string mNameSpace, string mClassName, string mDllProcName, object[] mObjArrayParams)
            {
                try
                {
                    // 载入程序集
                    Assembly mAssembly = Assembly.LoadFrom(mDllFileName);
                    Type[] mTypes = mAssembly.GetTypes();                foreach (Type mType in mTypes)
                    {
                        // 查找要调用的命名空间及类
                        if (mType.Namespace == mNameSpace && mType.Name == mClassName)
                        {
                            // 查找要调用的方法并进行调用
                            MethodInfo mMethod = mType.GetMethod(mDllProcName);                        if (mMethod != null)
                            {
                                object mObject = Activator.CreateInstance(mType);
                                return mMethod.Invoke(mObject, mObjArrayParams);
                            }
                            else
                            {
                                MessageBox.Show("Load Resource Dll File Failed!");
                            }
                        }
                    }
                }
                catch (Exception mEx)
                {
                    MessageBox.Show(mEx.Message);
                }            return (object)0;
            }        private void button1_Click(object sender, EventArgs e)
            {
                DllInvoke("DllForm.dll", "DllForm", "Class1", "ShowWindow", null);
            }
        }
    }子窗体:
    using System;
    using System.Collections.Generic;
    using System.Text;namespace DllForm
    {
        public class Class1
        {
            public void ShowWindow()
            {
                Form2 mForm = new Form2();
                mForm.Show();
            }    }
    }如果按照您的说法我应改如何改写?
      

  4.   

    1. Delegate
    2. 发送windows 消息
      

  5.   

    我现在想实现这样一种应用。主窗体是MDI窗体,在主窗体中有一些通用的按钮和事件,比如新增、编辑、保存、UNDO、REDO、删除、打印等功能。这些功能都分别对应当前处于激活状态的子窗体的事件,通过右键菜单来实现。
    子窗体是通过动态调用托管的DLL窗体来创建的。当子窗体中的右键菜单事件触发后,主窗体的按钮的状态应该相应的改变,比如说如果已经通过子窗体的邮件菜单完成了保存功能,那么对应在主窗体的存盘按钮应该DISABLE。
    不知道我说明白了没有。
      

  6.   

    Sample code as follows:1.Some modification in your dll as follows
    //Define an event handler
    public EventHandler myClick = null;
    // in some event function such click event
    if( myClick != null )
         myClick( sender, e );//to invoke event which is inited by main form2.Change your way to init child form in main formAssembly ass = Assembly.LoadFile( yourDllFile );
    if( ass != null )
    {
    Type typForm = ass.GetType( "Namespace.Formname" );
    if( typForm == null ) return;
    Form frmTest = typForm.InvokeMember( null,
    BindingFlags.DeclaredOnly |
    BindingFlags.Public | BindingFlags.NonPublic |
    BindingFlags.Instance | BindingFlags.CreateInstance,
    null,
    null,
    null ) as Form; if( frmTest == null ) return;        //Bind event here
    EventHandler eventClick = new EventHandler( MyClick );
    foreach( FieldInfo fi in typForm.GetFields(  ) )
    {
    if( fi.Name == "myClick" )
    fi.SetValue( frmTest,eventClick );
    }
    frmTest.ShowDialog();
    }//Define a function for child form
    public void MyClick( object sender, EventArgs e )
    {
    Debug.WriteLine( e.ToString() );
    }
      

  7.   

    哈哈,真的不错啊,基本上搞定了,我整理一下,明天把代码贴出来请Knight94(愚翁)兄再指点指点。
      

  8.   

    散分啦^_^,特别感谢Knight94(愚翁)兄。