仍然启用了显示Parent的ShowDialog

时间:2013-12-03 19:01:33

标签: c# multithreading winforms showdialog

在我们的某个应用中,我们希望限制用户在现有菜单项已打开时打开其他菜单项。我们目前正在这样做:

    private void menuItem1_Click(object sender, EventArgs e)
    {
         Myform f = new MyForm();
         f.ShowDialog(this);
    }

但是,在执行此操作时,我们失去了与父窗口进行交互的能力,因为在内部,parent.enabled属性设置为false。使用上面的代码,如果用户打开了菜单项并想要移动父窗口以查看其桌面上的内容,则他们首先必须关闭菜单项,移动父项,然后重新打开菜单项。

我已经提出了在后台工作中执行UI的以下方法

public class BaseForm : Form
{
    private bool _HasChildOpen;
    protected BackgroundWorker bgThead;

    public BaseForm()
    {
        _HasChildOpen = false;

        bgThead = new BackgroundWorker();
        bgThead.DoWork += new DoWorkEventHandler(OpenChildWindow);
        bgThead.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.ClearChildWindows);
    }


    protected void ClearChildWindows(object sender, RunWorkerCompletedEventArgs e)
    {
        _HasChildOpen = false;
    }

    public void OpenChildWindow(object sender, DoWorkEventArgs e)
    {
        if (!_HasChildOpen)
        {
            Form f = (Form)e.Argument;
            f.StartPosition = FormStartPosition.CenterScreen;
            f.ShowDialog();
        }
    }
}

然后每个菜单项都有以下代码

    private void menuItem1_Click(object sender, EventArgs e)
    {
        if (!bgThead.IsBusy)
        {
            bgThead.RunWorkerAsync(new Myform());
        }
    }

但是this approach is a big no no。但是,使用invoke似乎让我回到了我开始的地方:

    private void doUIWork(MethodInvoker d)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(d);
        }
        else
        {
            d();
        }
    }

    public void OpenChildWindow(object sender, DoWorkEventArgs e)
    {
        if (!_HasChildOpen)
        {

            doUIWork(delegate() {
                Form f = (Form)e.Argument;
                f.StartPosition = FormStartPosition.CenterScreen;
                f.ShowDialog();
            });

            //Form f = (Form)e.Argument;
            //f.StartPosition = FormStartPosition.CenterScreen;
            //f.ShowDialog();
        }
    }

如何正确地将用户限制为仅打开一个菜单项,但同时启用父级以便可以调整其大小等等?

1 个答案:

答案 0 :(得分:0)

一旦打开其中一个表单,您将需要以编程方式禁用菜单条行为。因此,如果您有Form1和Form2,(在Form1上使用menuStrip,在menuStrip上使用toolStripMenuItem1,toolStripMenuItem2):

    private void menuItem1_Click(object sender, EventArgs e)
    {
        var f2 = new Form2();
        f2.FormClosing += f2_FormClosing;
        f2.Show();
        this.menuStrip1.Enabled = false;
    }

    private void menuItem2_Click(object sender, EventArgs e)
    {
        var f2 = new Form2();
        f2.FormClosing += f2_FormClosing;
        f2.Show();
        this.menuStrip1.Enabled = false;
    }

    void f2_FormClosing(object sender, FormClosingEventArgs e)
    {
        this.menuStrip1.Enabled = true;
    }

使用Show()方法而不是ShowDialog()可以启用与父控件的交互,但是您需要手动禁用/启用行为,具体取决于子控件的显示时间。