0

I have a windows form with many controls. A tiny part of it is logging in to an SQL server and fetching the list of database names and assigning the collection to a combobox.

    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;
    }

I don't have a problem in fetching the list of Databases. It takes about 10 seconds to do so. With the messagebox in the event handler, I found out that the MouseClick event, for no apparent reason, gets fired like 38 times. The same thing happens even if I use the Enter event or Click event, instead of the MouseClick event.

Why does this happen, and how does one go about using these kind of events?

Thanks in advance, RPS.

Ren
  • 437
  • 4
  • 17
  • 1
    I guess, the event handler is getting hooked multiple times. But how do I know if the event is already hooked? – Ren May 09 '13 at 12:26

2 Answers2

3

If you want to get list of Databases, why don't you do so on Combobox value changed event?

Anyways,I see that you are doing

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

This should solve your problem

private void OnSQLServerChanged(object sender, EventArgs e)
    {
DatabaseCmbBox.MouseClick -= DatabaseCmbBox_Click;
        DatabaseCmbBox.MouseClick += DatabaseCmbBox_Click;
    }
Ehsan
  • 31,833
  • 6
  • 56
  • 65
  • The Combobox itself has to be populated with the list of databases.. But what's wrong with using either one of Click or enter or MouseClick events? Why would they get fired multiple times? – Ren May 09 '13 at 12:30
  • Thanks Ehsan. It works.. Got a question.. How many times would the TextChanged event be fired on the TextBox? Before the correction, the MouseClick event got fired like 38 times. Why could that have been? – Ren May 09 '13 at 12:39
  • Because you have linked it multiple times i.e. on every sql server changed you are hooking a new event without removing the previous one. Please mark it as answer. – Ehsan May 09 '13 at 12:39
1

This is a potential error: you should subscribe DatabaseCmbBox.MouseClick only once, not every time OnSQLServerChanged. Correct your code correspondingly, and the issue with multiple click events will be fixed:

private void OnSQLServerChanged(object sender, EventArgs e)
    {
        DatabaseCmbBox.MouseClick += DatabaseCmbBox_Click;
    }
Alexander Bell
  • 7,842
  • 3
  • 26
  • 42