有一个MDI窗提,为了防止重复打开相同的子窗体,我是这样处理的,代码如下:
这样处理也是没问题的。
private XFrmCompany xFrmCompany = null;private void barButtonItem29_ItemClick(object sender, 
DevExpress.XtraBars.ItemClickEventArgs e)
{
    if ((xFrmCompany == null) || xFrmCompany.IsDisposed)
    {
        xFrmCompany = new XFrmCompany();
        xFrmCompany.MdiParent = this;
        xFrmCompany.Show();
        MessageBox.Show(xFrmCompany.IsDisposed.ToString());
    }
    else
    {
        xFrmCompany.Activate();
    }
}=======================================================
由于子窗体太多,我于是确定把XFrmCompany作为参数传递过去,代码如下:
private XFrmCompany xFrmCompany = null;private void ShowChildForm(DevExpress.XtraEditors.XtraForm childForm, string className)
        {
            if ((childForm == null) || (childForm.IsDisposed))
            {
                Type classType = Type.GetType(className);
                if (classType != null)
                {
                    childForm = (DevExpress.XtraEditors.XtraForm)Activator.CreateInstance(classType);
                    childForm.MdiParent = this;
                    childForm.Show();
                }
            }
            else
            {
                childForm.Activate();
            }
        } private void barButtonItem29_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            ShowChildForm(xFrmCompany, "Production.XFrmCompany");
        }这样可以打开子窗体,但会重复打开相同的子窗体。
请教:怎样用第二种方法,避免打开相同的子窗体。

解决方案 »

  1.   

    bool  OpenOnce(Form frm)
    {
    foreach(Form mdifrm in this.MdiChildren)
    {
    if(frm.Text==mdifrm.Text)
    {
    mdifrm.Activate();
    return false;
    }
    }
    return true;
    }
      

  2.   

    先查窗体有没被创建,然后再选择是不是要重复打开。
    2005下使用:
            /// <summary>
            /// 查找是否已创建窗体
            /// </summary>
            /// <param name="FormName">窗体Name</param>
            /// <returns></returns>
            public static bool SearchAllForm(string FormName)
            {
                for (int i = 0; i < Application.OpenForms.Count; i++)
                {
                    if (Application.OpenForms[i].Name == FormName)
                    {
                        return true;
                    }
                }
                return false;
            }
    2003下使用:        [DllImport("User32.dll", EntryPoint = "FindWindow")]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);        [DllImport("user32.dll", EntryPoint = "FindWindowEx")] //找子窗体
            private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);        [DllImport("User32.dll", EntryPoint = "SendMessage")] //用于发送信息给窗体
            private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam); 
            /// <summary>
            /// 查找是否已创建窗体
            /// </summary>
            /// <param name="FormTitle">标题名称</param>
            /// <returns></returns>
            public static bool SearchForm(string FormTitle)
            {
                IntPtr ParenthWnd = new IntPtr(0);
                IntPtr EdithWnd = new IntPtr(0);            //查到窗体,得到整个窗体 
                ParenthWnd = FindWindow(null,FormTitle);
                if (!ParenthWnd.Equals(IntPtr.Zero))
                {
                    return true;
                }
                else
                {
                    return false;
                }        }
      

  3.   

    楼上到方法太麻烦了,在网上找了一段代码,和我的想法相同,研究一下先:
     如何在MDI中使子窗体只保留一个实例 
    由于在MDI中,子窗体会很多,那么在我以前一篇文章中所提到的方法就有些繁琐了。为了能适应多个子窗体,并对于每个子窗体只保留一个实例,那么我就用一个新的方法来替换,即用反射方法来作处理。 大致代码如下。首先是通过子窗体类型名来判断是否打开新的子窗体,还是把原有的子窗体进行显示。    using System.Reflection;    /// <summary>    /// Open child window    /// </summary>    /// <param name="ChildTypeString"></param>    private void OpenWindow( string ChildTypeString )    {        Form myChild = null;        if( !ContainMDIChild( ChildTypeString ) )        {            // Get current process assembly            Assembly assembly = Assembly.GetExecutingAssembly();             // Create data type using type string            Type typForm = assembly.GetType( ChildTypeString );             // Create object using type's "InvokeMember" method            Object obj = typForm.InvokeMember(                null,                 BindingFlags.DeclaredOnly |                 BindingFlags.Public | BindingFlags.NonPublic |                 BindingFlags.Instance | BindingFlags.CreateInstance,                 null,                 null,                null );             // Show child form             if( obj != null )            {                myChild = obj as Form;                myChild.MdiParent = this;                myChild.Show();                myChild.Focus();            }        }    }     /// <summary>    /// Search mdi child form by specific type string    /// </summary>    /// <param name="ChildTypeString"></param>    /// <returns></returns>    private bool ContainMDIChild( string ChildTypeString )     {        Form myMDIChild = null;        foreach(Form f in this.MdiChildren)         {             if( f.GetType().ToString() == ChildTypeString )             {                 // found it                 myMDIChild = f;                 break;             }         }          // Show the exist form        if( myMDIChild != null)         {             myMDIChild.TopMost = true;            myMDIChild.Show();             myMDIChild.Focus();             return true;        }         else            return false;    } 以上两部分就可以对于每个子窗体只创建一个实例。那么调用以上代码就非常简单了。如:    //Open a mdi child form which type named "MDIChild"    OpenWindow( typeof( MDIChild ).ToString() );