C # WinForms Combobox.DropDownStyle иногда вызывает исключение при изменении - PullRequest
0 голосов
/ 28 октября 2019

У меня есть форма, которая использует 2 поля со списком для выбора задания и запрос SQL для редактирования / создания. Если поле со списком имеет индекс 0, я устанавливаю DropDownStyle равным DropDownStyle.DropDown, чтобы пользователь мог редактировать текст. Когда они нажимают ввод, он создает новое задание или запрос в зависимости от того, какое поле со списком они использовали, и добавляет его в соответствующее поле. Если поля имеют любой другой индекс, я устанавливаю DropDownStyle равным DropDownStyle.DropDownList, чтобы текст не редактировался.

Иногда при изменении DropDownStyle выдается исключение System.AccessViolationException:

Исключение

Я обернул код, который изменяет DropDownStyle в блоки try-catch и ставит точки останова в блоки catch, но он не ломается в этих точках и вместо этого ломаетсяпри звонке, который показывает форму. Вот 2 метода в форме, которые изменяют DropDownStyle:

        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 CboQuery_SelectedIndexChanged(object sender, EventArgs e)
        {

            try
            {
                cboQuery.DropDownStyle = ComboBoxStyle.DropDownList;
            }
            catch (Exception ex)
            {
                throw;
            }
            if (cboQuery.SelectedIndex > 0)
            {
                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;
                }
            }
        }

Это метод, который показывает форму:

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

Я думаю, причина, почемублоки catch не перехватывают это потому, что код, который вызывает исключение, представляет собой Windows DLL, называемую «comctl32.dll». Если я включаю отладку собственного кода, я получаю следующее исключение:

исключение собственного кода

Я искал повсюду информацию об этом и не смогнайди что нибудь полезное. Я запустил тест памяти на компьютере, и он вышел нормально. Есть идеи?

Спасибо!

1 Ответ

0 голосов
/ 29 октября 2019

На первый взгляд, есть проблема в строке

if (_jobs[cboJob.SelectedIndex - 1].Queries.Count > 0)

Когда cboJob.SelectedIndex равно 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;
                }
            }
        }

Это должно помочь избежать отрицательной индексации в коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...