2013-03-28 53 views
0

我试图锁定主窗体,而请稍候框显示在屏幕上,但它不起作用。这是我的困境。在C#中,你如何锁定表单?

我有2种形式。用户单击刷新按钮加载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; 
     } 
    } 
+1

什么是'锁定表单'?防止用户在执行这些功能时单击控件? – IAbstract 2013-03-28 03:23:32

+1

Imho你应该打开你的“Please wait”框作为对话框。然后,下面的表单被“锁定”。 – 2013-03-28 04:13:01

回答

0

我想你是在一个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(); 

正如你所知道的,因为它不会在UI线程上运行您不能更新从bg_DoWork处理程序的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; 
} 
+0

非常好。这很好。谢谢。 =) – 2013-03-29 07:54:29