Проблема с обработкой кликов DataGridViewCheckBoxCell

Я создал элемент управления DataGridView, в котором первый столбец является флажком. Когда я щелкаю внутри флажка, код выполняется правильно. ОДНАКО, когда щелчок происходит в ячейке, а не в флажке, код правильно обрабатывает состояние флажка, но не обновляет сам флажок, поэтому он остается в том состоянии, в котором он был до щелчка.

Как это исправить?

   private void myDataGrid_CellClick(object sender, DataGridViewCellEventArgs e)
   {
       if (e.RowIndex == -1) return; //check if row index is not selected
       DataGridViewCheckBoxCell ch1 = new DataGridViewCheckBoxCell();
       ch1 = (DataGridViewCheckBoxCell)myDataGrid.Rows[e.RowIndex].Cells[0];

       if (ch1.Value == null)
           ch1.Value = false;
       switch (ch1.Value.ToString())
       {
           case "False":

               ch1.Value = true;

               break;
           case "True":

               ch1.Value = false;
               break;
       }
      //BUT doesn't seem to matter what I do with ch1.Value. Inside the checkbox all is OK but
      //outside, no.

   }

Если я щелкну другую ячейку в строке, флажок будет обработан правильно. ТОЛЬКО когда я нажимаю в ячейке флажка, но НЕ в самом флажке.

Я имею в виду (и приношу извинения), что код выполняется правильно, но пользовательский интерфейс не обновляется должным образом, чтобы отразить изменение. Таким образом, если флажок снят до того, как он появится после введите здесь описание изображения, даже если он действительно проверяется.

Спасибо РОН


person Ron    schedule 26.12.2013    source источник
comment
Можете ли вы предоставить свой код?   -  person tilda    schedule 27.12.2013


Ответы (2)


Я не уверен на 100 %, что вызывает такое поведение, но я считаю, что это связано с тем, что ячейка флажка переходит в режим редактирования в тот момент, когда вы щелкаете внутри нее. Подтверждено, что эта проблема определенно вызвана вход в режим редактирования в тот момент, когда вы щелкаете внутри ячейки. Смотрите редактирование в конце поста.

Поскольку вы сами устанавливаете значение ячейки, вы можете обойти эту проблему, просто сделав столбец флажка доступным только для чтения.

Следующий код отлично работал у меня при использовании LINQPad (я смотрю на вольности, чтобы упростить логику обработчика):

void Main()
{
    var dataGridView = new DataGridView();
    dataGridView.Columns.Add(new DataGridViewCheckBoxColumn());
    dataGridView.Columns.Add(new DataGridViewTextBoxColumn());
    dataGridView.Columns.Add(new DataGridViewTextBoxColumn());

    dataGridView.Columns[0].ReadOnly = true;
    dataGridView.Columns[1].ReadOnly = true;
    dataGridView.Columns[2].ReadOnly = true;

    dataGridView.CellClick += this.DataGridView_CellClick;

    dataGridView.Dump();
}

void DataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex < 0) return;

    var dataGridView = (DataGridView) sender;
    var cell = dataGridView[0, e.RowIndex];

    if (cell.Value == null) cell.Value = false;
    cell.Value = !(bool)cell.Value;
}

Единственная странность, которую я заметил, заключается в том, что второй щелчок в двойном щелчке не направляется в обработчик событий CellClick. Если вам действительно нужно такое поведение, вы можете привязать тот же обработчик к событию CellDoubleClick.

Редактировать:

Если вам не нравится делать первый столбец доступным только для чтения, вы можете просто добавить вызов EndEdit после изменения значения:

void DataGridView_CellClick(object sender, DataGridViewCellEventArgs e)
{
    if (e.RowIndex < 0) return;

    var dataGridView = (DataGridView) sender;
    var cell = dataGridView[0, e.RowIndex];

    if (cell.Value == null) cell.Value = false;
    cell.Value = !(bool)cell.Value;
    dataGridView.EndEdit();
}

На это намекал комментарий к другому вопросу пользователя NeverHopeless.

person Anthony    schedule 26.12.2013

Я на 100% уверен. Я сделал хорошо.

 /// <summary>
    ///データグリッドビューのチェックボックスのダブルクリックイベント
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Ichiran_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
    {
        this.Ichiran_CheckBoxCellClick(sender, e);
    }

    /// <summary>
    /// データグリッドビューのチェックボックスのクリックイベント
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Ichiran_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        this.Ichiran_CheckBoxCellClick(sender, e);
    }

    /// <summary>
    /// セルの値自体がクリックされた際に発生するCellContentClickイベントの
    /// コールバックメソッドです。
    /// </summary>
    /// <param name="sender">イベント送信元オブジェクト</param>
    /// <param name="e"></param>              
    private void Ichiran_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        this.Ichiran_CheckBoxCellClick(sender, e);
    }

    /// <summary>
    /// チェックボックスクリック
    /// </summary>
    private void Ichiran_CheckBoxCellClick(object sender, DataGridViewCellEventArgs e)
    {
        if (this.Ichiran.CurrentCell != null && this.Ichiran.CurrentCell is r_framework.CustomControl.DataGridCustomControl.DgvCustomCheckBoxCell)
        {
            if (e.RowIndex < 0)
            {
                return;
            }
            var cell = this.Ichiran["chb_delete", e.RowIndex];
            if (cell.Value == null) cell.Value = false;
            cell.Value = !(bool)cell.Value;
            cell.ReadOnly = true;
            cell.ReadOnly = false;
        }
    }

    /// <summary>
    /// CurrentCellDirtyStateChangedイベントハンドラでDataGridView.CommitEditメソッドを呼び出して値をコミットします。
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void Ichiran_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        this.Ichiran.CommitEdit(DataGridViewDataErrorContexts.Commit);

    }
person Xe đạp đôi Hoàng    schedule 19.08.2015