在c#中,如何锁定表单

本文关键字:锁定 表单 何锁定 | 更新日期: 2023-09-27 18:06:27

我试图锁定主表单,而请等待框显示在屏幕上,但它不会工作。这就是我的困境。

我有两个表格。用户单击刷新按钮加载SQL server列表的主要表单,以及在加载列表时显示的请等待表单。在使用c#时,SQL Server线程默认是一个单独的线程,它锁住主线程以处理SQL请求。

我可以添加一个后台工作者,但是我不能更新我的组合框来显示列表作为它的UI控件。如果我使用处理程序,我的show_dialog()的请等待框将停止锁定主表单。

在主线程再次激活后,如何在没有左键队列的情况下锁定此表单?我添加了需要在用户等待时执行的代码。

    public void PullServers()
    {
        bool ServersFound = false;
        foreach (string Value in SQL.LocateSqlInstances())
        {
            this.cmbServer.Items.Add(Value);
            ServersFound = true;
        }
        if (!ServersFound)
        {
            this.cmbServer.Items.Add(Strings.Lang("ddServerNoneFound"));
            this.cmbServer.SelectedIndex = 0;
        }
        else
        {
            if (!s.empty(General.setting("SQLSERVER")))
            {
                this.cmbServer.Text = General.setting("SQLSERVER");
            }
            else
            {
                this.cmbServer.SelectedIndex = 0;
            }
        }
        this.picRefreshServers.Image = Properties.Resources.Refresh;
    }
    public static Array LocateSqlInstances()
    {
        using (DataTable sqlSources = System.Data.Sql.SqlDataSourceEnumerator.Instance.GetDataSources())
        {
            string Servers = null;
            foreach (DataRow source in sqlSources.Rows)
            {
                string instanceName = source["InstanceName"].ToString();
                if (!s.empty(instanceName))
                {
                    Servers += source["ServerName"].ToString() + "''" + instanceName + "[[SERVBREAK]]";
                }
            }
            string[] ServersList = Servers.Split(new string[] { "[[SERVBREAK]]" }, StringSplitOptions.RemoveEmptyEntries);
            return ServersList;
        }
    }

在c#中,如何锁定表单

我认为您使用BackgroundWorker的方法是正确的。我发现下面的模式对我很有效。

在主表单中,需要执行以下步骤:

  1. 创建一个BackgroundWorker来执行长时间运行的操作。
  2. 启动BackgroundWorker
  3. 将等待表单显示为模态对话框。
// Step 1:
BackgroundWorker bg = new BackgroundWorker()
bg.DoWork += new DoWorkEventHandler(bg_DoWork);
bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
// Step 2:
bg.RunWorkerAsync();
// Step 3:
waitingForm = new WaitingForm();
waitingForm.ShowDialog();

如你所知,你不能从bg_DoWork处理程序更新UI,因为它不在UI线程上运行。因此,只需在这里获取所需的数据,并使用e.Result参数将其传递给bg_RunWorkerCompleted处理程序。

private void bg_DoWork(object sender, DoWorkEventArgs e)
{
    Array servers = SQL.LocateSqlInstances();
    e.Result = servers;
}

bg_RunWorkerCompleted在UI线程上运行,所以在这里更新控件是安全的。在这里,您应该关闭等待表单,然后更新您的UI。

private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Close the Waiting form.
    waitingForm.Close();
    // Retrieve the result of bg_DoWork().
    Array servers = e.Result as Array;
    bool ServersFound = false;
    foreach (string Value in servers)
    {
        this.cmbServer.Items.Add(Value);
        ServersFound = true;
    }
    if (!ServersFound)
    {
        this.cmbServer.Items.Add(Strings.Lang("ddServerNoneFound"));
        this.cmbServer.SelectedIndex = 0;
    }
    else
    {
        if (!s.empty(General.setting("SQLSERVER")))
        {
            this.cmbServer.Text = General.setting("SQLSERVER");
        }
        else
        {
            this.cmbServer.SelectedIndex = 0;
        }
    }
    this.picRefreshServers.Image = Properties.Resources.Refresh;
}