类似模态的用户控制

时间:2017-09-13 17:26:50

标签: c# winforms

我有一个使用拆分容器的多标签winform。在右侧选项卡中,我使用左侧选项卡显示/隐藏用户控件。某些用户控件需要在其上显示新的用户控件。问题是当原始用户控件显示新的用户控件时,我希望第一个用户控件等待新的用户控件关闭(有些像表单中的ShowDialog),但是这个屏幕锁定只会在一个选项卡中出现。

我尝试了Threads和许多其他解决方案,但没有一个按我的意愿工作。

{
    var panel = (Panel)this.Parent;
    var searchUserControl = new searchUserControl();
    searchUserControl.Parent = this;
    panel.Controls.Add(searchUserControl);
    this.visible = false; // hides the original form
    // wait
    this.visible = true; // shows the original form again
    var result = searchUserControl.CustomProperty;
}

1 个答案:

答案 0 :(得分:1)

如果您使用一些技巧,可以使用async / await来执行此操作。

关键因素是TaskCompletionSource。它代表Task的“状态”,并允许您从代码中的另一个点“完成”它,在这种情况下,是“对话框”上的一个按钮。

创建一个UserControl来代表您的“对话框”,给它“确定”和“取消”按钮,或者您需要的任何按钮。

UserControl的代码隐藏应该如下所示:

public partial class DialogControl : UserControl
{
    TaskCompletionSource<DialogResult> _tcs;

    public DialogControl()
    {
        InitializeComponent();
        this.Visible = false;
    }

    public Task<DialogResult> ShowModalAsync()
    {
        _tcs = new TaskCompletionSource<DialogResult>();

        this.Visible = true;
        this.Dock = DockStyle.Fill;
        this.BringToFront();
        return _tcs.Task;
    }

    private void btmCancel_Click(object sender, EventArgs e)
    {
        this.Visible = false;
        _tcs.SetResult(DialogResult.Cancel);
    }

    private void btnOk_Click(object sender, EventArgs e)
    {
        _tcs.SetResult(DialogResult.OK);
        this.Visible = false;
    }

    public string UserName
    {
        get { return txtName.Text; }
        set { txtName.Text = value; }
    }
}

主窗体上的Button可以使用此代码显示“模态控件”:

private async void btnShowDialogControl_Click(object sender, EventArgs e)
{
    var control = new DialogControl();
    splitContainer1.Panel2.Controls.Add(control);

    //Disable your other controls here


    if (await control.ShowModalAsync() == DialogResult.OK) //Execution will pause here until the user closes the "dialog" (task completes), just like a modal dialog.
    {
        MessageBox.Show($"Username: {control.UserName}");
    }

    //Re-enable your other controls here.

    splitContainer1.Panel2.Controls.Remove(control);
}

可以从here下载完整的工作解决方案源代码。