c# Windows窗体,组合框鼠标点击事件被触发多次

本文关键字:事件 窗体 Windows 组合 鼠标 | 更新日期: 2023-09-27 18:12:44

我有一个带有许多控件的windows窗体。它的一小部分是登录到SQL服务器并获取数据库名称列表并将集合分配给组合框。

    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事件,也会发生同样的事情。

为什么会发生这种情况,人们如何使用这类事件?

提前感谢,rp。

c# Windows窗体,组合框鼠标点击事件被触发多次

如果您想获得数据库列表,为什么不在组合框值更改事件上这样做?

无论如何,我看到你在做

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

这是一个潜在的错误:您应该只订阅一次DatabaseCmbBox.MouseClick,而不是每次都订阅OnSQLServerChanged。相应地更正您的代码,多个单击事件的问题将得到修复:

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