用户不耐烦地多次点击menuitem多次加载MDI子表单

时间:2011-07-25 16:34:41

标签: c# winforms

我希望MDI Parent只加载一些表单。因此,在menuitem的click事件中,我查看MDI父级的.Children属性是否已经包含该表单,并且仅当表单不在子级中时才加载表单:

       bool alreadyLoaded = false;
       if (this.MdiChildren.Length > 0)
            {
                foreach (Form frm in this.MdiChildren)
                {
                    if (frm.Name == "foo")
                    {
                        alreadyLoaded=true;
                        break;
                    }
                }
            }


            if (! alreadyLoaded)
            {
               FOO f = new FOO();
               f.MdiParent=this;
               f.Show();
            }

但是,如果不耐烦的用户在第一次加载表单时快速点击菜单项,则可以多次加载。在第一次单击加载的实例完全实例化之前,第二次和第三次单击菜单项将启动表单的新副本。

我想我可以维护自己的已启动表单名称列表,并在menuitem的click事件处理程序中,将表单的名称添加到列表中(如果它尚不存在),稍后将其从子表单中的列表中删除事件处理程序。但是有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

试试这堂课:

/// <summary>
/// Displays form in mdi form once
/// </summary>
/// <autor>Saber Amani</autor>
/// <lastUpdate>2009-03-03</lastUpdate>
public class MdiFormDisplayer
{
    private Hashtable fForms = new Hashtable();
    private object fSender = null;

    public MdiFormDisplayer(object sender)
    {
        fSender = sender;
    }

    public Form GetForm(Type formType)
    {
        string formName = formType.Name;
        Form frm = (Form)fForms[formName];
        if (frm == null || frm.IsDisposed)
        {
            frm = CreateNewInstance(formType);
            fForms[formName] = frm;
        }
        return frm;
    }

    public Form GetForm(string formName)
    {
        if (fSender == null)
            throw new ArgumentNullException("Sender", "Sender can't be null");
        return GetForm(fSender, formName);
    }

    public Form GetForm(object sender, string formName)
    {
        Form frm = (Form)fForms[formName];
        if (frm == null || frm.IsDisposed)
        {
            frm = CreateNewInstance(sender, formName);
            fForms[formName] = frm;
        }
        return frm;
    }

    private Form CreateNewInstance(object sender, string formName)
    {
        Type frmType;
        frmType = FindFormType(sender, formName);
        Form frmInstance = (Form)CallTypeConstructor(frmType);

        return frmInstance;
    }

    private Form CreateNewInstance(Type frmType)
    {
        Form frmInstance = (Form)CallTypeConstructor(frmType);
        return frmInstance;
    }

    private Type FindFormType(object sender, string formName)
    {
        Type baseType = sender.GetType();
        Assembly senderAssembly = Assembly.GetAssembly(baseType);

        Type result = null;

        // Search with assembly standard method
        result = senderAssembly.GetType(baseType.Namespace + "." + formName);
        if (result != null)
            return result;

        // Search with in the types
        Type[] assemblyTypes = senderAssembly.GetTypes();
        formName = formName.ToLower();
        for (int i = 0; i < assemblyTypes.Length; i++)
        {
            if (assemblyTypes[i].Name.ToLower() == formName)
                return assemblyTypes[i];
        }

        return null;
    }

    private object CallTypeConstructor(Type frmType)
    {
        Type[] contructTypes = new Type[] { };
        ConstructorInfo constructorObj = frmType.GetConstructor(contructTypes);
        object result = constructorObj.Invoke(null);
        return result;
    }


}

像这样使用:

    public partial class frmMainForm : Form
    {
       MdiFormDisplayer forms;

       public frmMainForm()
       {
           InitializeComponent();
           forms = new MdiFormDisplayer(this);
       }

       private void btnCompany_Click(object sender, EventArgs e)
       {
           Form frm = forms.GetForm(typeof(frmCompany));

           frm.MdiParent = this;
           frm.Show();
           frm.Focus();
       }

    }

希望得到这个帮助。

答案 1 :(得分:0)

在调用菜单处理程序时设置的简单标志 - 称为“processingClick”。如果已设置此标志,则退出处理程序。请记住在例程结束时将其重置为false。

或者你可以在菜单处理程序的内容周围放置一个很重要的部分 - 所以如果它快速连续点击两次,第二次点击将等待第一个处理。这可以保证您的第一次点击可以完成所有处理。

答案 2 :(得分:0)

你可以在安装相应的表格之前直接点击第一次点击菜单项...然后在关闭表格时你可以重新启用菜单项......这样用户就无法按你所描述的那样做... < / p>