2013-05-09 99 views
0

我有一個windows窗體與許多控件。它的一小部分將登錄到SQL服務器並獲取數據庫名稱列表並將該集合分配給組合框。C#Windows窗體,Combobox MouseClick事件被多次觸發

private void InitializeComponent() 
    { 

     //... 
     //... 
     this.ServerTB = new System.Windows.Forms.TextBox(); 
     this.UserNameTB = new System.Windows.Forms.TextBox(); 
     this.PasswordTB = new System.Windows.Forms.TextBox(); 
     //... 
     //... 

     this.ServerTB.TextChanged += new System.EventHandler(this.OnSQLServerChanged); 
     this.UserNameTB.TextChanged += new System.EventHandler(this.OnSQLServerChanged);  
     this.PasswordTB.TextChanged += new System.EventHandler(this.OnSQLServerChanged);  


     this.DatabaseCmbBox = new System.Windows.Forms.ComboBox(); 
     //... 
     //... 
     this.DatabaseCmbBox.MouseClick += new System.Windows.Forms.MouseEventHandler(this.DatabaseCmbBox_Click); 

     //.... 

    } 

    private void DatabaseCmbBox_Click(object sender, MouseEventArgs e) 
    { 
     MessageBox.Show(sender.GetType().ToString()); 

     this.Cursor = Cursors.IBeam; 

     List<string> dbList = new List<string>(); 

     dbList = GetDatabaseList(); 

     DatabaseCmbBox.DataSource = dbList; 

     DatabaseCmbBox.SelectedIndex = -1; 


     if (dbList.Count > 0) 
     { 
      DatabaseCmbBox.MouseClick -= DatabaseCmbBox_Click; 
     } 


     DatabaseCmbBox.Focus(); 

     this.Cursor = Cursors.Default; 
    } 

    protected List<string> GetDatabaseList() 
    { 
     List<string> list = new List<string>(); 

     string conString = "server=" + ServerTB.Text + ";uid=" + UserNameTB.Text + ";pwd=" + PasswordTB.Text + "; database=master"; 

     try 
     { 

      using (SqlConnection con = new SqlConnection(conString)) 
      { 
       con.Open(); 

       using (SqlCommand cmd = new SqlCommand("select name from sys.databases where name not in ('master', 'model', 'tempdb', 'msdb') ", con)) 
       { 
        using (IDataReader dr = cmd.ExecuteReader()) 
        { 
         while (dr.Read()) 
         { 
          list.Add(dr[0].ToString()); 
         } 

         dr.Close(); 
        } 

        cmd.Dispose(); 
       }      

       con.Close(); 
      } 
     } 
     catch(SqlException ex) 
     { 
      DatabaseCmbBox.MouseClick -= DatabaseCmbBox_Click; 
      MessageBox.Show(ex.Message); 
      ServerTB.Focus(); 
     } 

     return list; 

    } 

    private void OnSQLServerChanged(object sender, EventArgs e) 
    { 
     DatabaseCmbBox.MouseClick += DatabaseCmbBox_Click; 
    } 

我在獲取數據庫列表時沒有問題。這需要大約10秒鐘的時間。通過事件處理程序中的消息框,我發現MouseClick事件無緣無故地被解僱了38次。即使我使用Enter事件或Click事件,而不是MouseClick事件,也會發生同樣的事情。

爲什麼會發生這種情況,以及如何使用這些事件?

在此先感謝, RPS。

+1

我想,事件處理程序會掛鉤多次。但是我怎麼知道這個事件是否已經被吸引了? – 2013-05-09 12:26:39

回答

3

如果你想獲得數據庫列表,爲什麼你不這樣做combobox值更改事件?

不管怎麼說,我看到你在做

private void OnSQLServerChanged(object sender, EventArgs e) 
    { 
     DatabaseCmbBox.MouseClick += DatabaseCmbBox_Click; 
    } 

這應該解決您的問題

private void OnSQLServerChanged(object sender, EventArgs e) 
    { 
DatabaseCmbBox.MouseClick -= DatabaseCmbBox_Click; 
     DatabaseCmbBox.MouseClick += DatabaseCmbBox_Click; 
    } 
+0

Combobox本身必須填充數據庫列表。但是,使用Click或Enter或MouseClick事件中的任何一個有什麼問題?他們爲什麼會被解僱多次? – 2013-05-09 12:30:15

+0

謝謝Ehsan。它的工作..有一個問題.. TextChanged事件在TextBox上被觸發多少次?在更正之前,MouseClick事件被解僱了38次。爲什麼會這樣? – 2013-05-09 12:39:25

+0

因爲您已經多次鏈接過它,即在每個更改的sql服務器上,您都會掛鉤新事件而不刪除前一個。請標記爲答案。 – Ehsan 2013-05-09 12:39:57

1

這是一個潛在的錯誤:你應該訂閱DatabaseCmbBox.MouseClick只有一次,而不是每次都OnSQLServerChanged。相應地修正你的代碼,並且多個點擊事件的問題將被修復:

private void OnSQLServerChanged(object sender, EventArgs e) 
    { 
     DatabaseCmbBox.MouseClick += DatabaseCmbBox_Click; 
    }