C#WinForms Combobox.DropDownStyle有时在更改时会导致异常

C#WinForms Combobox.DropDownStyle有时在更改时会导致异常,c#,winforms,combobox,C#,Winforms,Combobox,我有一个表单,它使用两个组合框来选择一个作业和一个要编辑/创建的SQL查询。如果组合框在索引0处,我将DropDownStyle设置为DropDownStyle.DropDown,以便用户可以编辑文本。当他们按enter键时,它将根据他们使用的组合框创建一个新作业或查询,并将其添加到相应的框中。如果框位于任何其他索引,我将DropDownStyle设置为DropDownStyle.DropDownList,因此文本不可编辑 有时,更改DropDownStyle时,会引发System.Access

我有一个表单,它使用两个组合框来选择一个作业和一个要编辑/创建的SQL查询。如果组合框在索引0处,我将DropDownStyle设置为DropDownStyle.DropDown,以便用户可以编辑文本。当他们按enter键时,它将根据他们使用的组合框创建一个新作业或查询,并将其添加到相应的框中。如果框位于任何其他索引,我将DropDownStyle设置为DropDownStyle.DropDownList,因此文本不可编辑

有时,更改DropDownStyle时,会引发System.AccessViolationException:

我已经包装了在try-catch块中更改DropDownStyle并在catch块中放置断点的代码,但是它不会在这些点中断,而是在显示表单的调用中中断。 以下是表单中更改下拉样式的两种方法:

        private void CboJob_SelectedIndexChanged(object sender, EventArgs e)
        {

            try
            {
                cboJob.DropDownStyle = ComboBoxStyle.DropDownList;
            }
            catch (Exception ex)
            {
                throw;
            }
            txtSQL.TextChanged -= TxtSQL_TextChanged;
            txtSQL.Text = "";
            txtSQL.Enabled = false;
            txtSQL.TextChanged += TxtSQL_TextChanged;
            cboQuery.Items.Clear();
            if (cboJob.SelectedIndex > 0)
            {
                cboQuery.Enabled = true;
                btnDeleteJob.Enabled = true;
                cboQuery.Items.Add("<New Query>");
                cboQuery.Items.AddRange(_jobs[cboJob.SelectedIndex - 1].Queries.ToArray());
                if (cboQuery.Items.Count > 1)
                {
                    cboQuery.SelectedIndex = 1;
                }
                else
                {
                    cboQuery.SelectedIndex = 0;
                }
            }
            else
            {
                cboQuery.Enabled = false;
            }
            if (cboJob.SelectedIndex == 0)
            {
                try
                {
                    cboJob.DropDownStyle = ComboBoxStyle.DropDown;
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
        }
这是显示表单的方法:

        private void BtnEdit_Click(object sender, EventArgs e)
        {
            var frmSQL = new EditSQLForm();

            try
            {
                if (frmSQL.ShowDialog() == DialogResult.OK)//this is the line it breaks at
                {
                    _jobs = frmSQL.Jobs;
                    Save();
                    GetData();
                }
            }
            catch (Exception ex)
            {

                throw;
            }
            frmSQL.Dispose();
        }
我认为try-catch块无法捕获它的原因是引发异常的代码是一个名为“comctl32.DLL”的Windows DLL。如果启用本机代码调试,则会出现以下异常:

我找遍了所有的地方,找不到任何有用的信息。我在电脑上做了一个内存测试,结果是正常的。有什么想法吗


谢谢

乍一看,线路中有一个问题

if (_jobs[cboJob.SelectedIndex - 1].Queries.Count > 0)
cboJob.SelectedIndex
为0时,将在此处引发异常。尝试添加一个附加条件(以下是您的代码+修改行中的我的注释):


这将有助于避免代码中的负索引。

设置组合框的
下拉样式时,将重新创建控件的句柄。它以前的句柄不再有效。
if (_jobs[cboJob.SelectedIndex - 1].Queries.Count > 0)
        private void CboQuery_SelectedIndexChanged(object sender, EventArgs e)
        {

            try
            {
                cboQuery.DropDownStyle = ComboBoxStyle.DropDownList;
            }
            catch (Exception ex)
            {
                throw;
            }
            if (cboQuery.SelectedIndex > 0 && cboJob.SelectedIndex > 0) // ADDITIONAL CONDITION!
            {
                if (_jobs[cboJob.SelectedIndex - 1].Queries.Count > 0)
                {
                    txtSQL.Enabled = true;
                    btnDeleteQuery.Enabled = true;
                    txtSQL.Text = _jobs[cboJob.SelectedIndex - 1].Queries[cboQuery.SelectedIndex - 1].Sql;
                }
                else
                {
                    btnDeleteQuery.Enabled = false;
                    txtSQL.Enabled = false;
                }
            }
            else
            {
                btnDeleteQuery.Enabled = false;
                txtSQL.Enabled = false;
            }
            if (cboQuery.SelectedIndex == 0)
            {
                try
                {
                    cboQuery.DropDownStyle = ComboBoxStyle.DropDown;
                }
                catch (Exception ex)
                {
                    throw;
                }
            }
        }