Вопрос по c# – DataGridView - как сделать флажок переключателем?

3

У меня есть приложение Windows Forms, которое отображает список объектов вDataGridView.

Этот элемент управления отображает значения bool как флажки.

Существует набор из трех флажков в свойствах объекта, которые являются взаимоисключающими. Максимум один из них может быть правдой. Соответственно, я хотел бы, чтобы флажки действовали как набор переключателей.

Just a side remark from the old guy: I think people these days don't even know why these are called radio buttons. In the old days a radio in a car had 4 or 5 buttons, and depressing any one of them caused all the others to pop out. They were mutually exclusive. "Radio button" is probably not a helpful description these days because radios don't have buttons like that anymore, I don't think.

Как мне это сделать? Я полагаю, если я прикреплю & quot; CheckedChanged & quot; Событие с флажками, и я знаю строку, я смогу найти все остальные флажки.

Какое событие можно перехватить, чтобы получить элемент управления checkbox при его первом отображении, чтобы я мог прикрепить к нему событие CheckedChanged? Я знаю оDataGridView.CellFormatting, но я думаю, что это неправильно, потому что он вызывается каждый раз, когда рисует DataGridView. Мне действительно нужно событие, которое вызывается только при первом рендеринге DGV.

Ваш Ответ

4   ответа
1
  private void dataGridViewProduit_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
        if ((sender as DataGridView).CurrentCell is DataGridViewCheckBoxCell)
        {
            if (Convert.ToBoolean(((sender as DataGridView).CurrentCell as DataGridViewCheckBoxCell).Value))
            {
                foreach (DataGridViewRow row in (sender as DataGridView).Rows)
                {
                    if (row.Index != (sender as DataGridView).CurrentCell.RowIndex && Convert.ToBoolean(row.Cells[e.ColumnIndex].Value) == true)
                    {
                        row.Cells[e.ColumnIndex].Value = false;
                    }
                }
            }
        }
    }

    private void dataGridViewClient_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        if (this.dataGridViewClient.IsCurrentCellDirty)
        {
            dataGridViewClient.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }
0

Обратите внимание, что ваш столбец флажка является вторым столбцом в вашей таблице данных.

private void YourDatagridview_CellValueChanged(object sender, DataGridViewCellEventArgs e)
    {
         if (IsHandleCreated)
        {
            if (YourDatagridview.CurrentCell == YourDatagridview.Rows[e.RowIndex].Cells[1])
            {
                if (Convert.ToBoolean(YourDatagridview.CurrentCell.Value) == true)
                {
                    for (int i = 0; i < YourDatagridview.RowCount; i++)
                    {
                        if (YourDatagridview.Rows[i].Cells[1] != YourDatagridview.CurrentCell)
                        {
                            YourDatagridview.Rows[i].Cells[1].Value = false;
                        }
                    }
                }
            }
        }
    }

И назовите это тоже:

private void YourDatagridview_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        if (this.YourDatagridview.IsCurrentCellDirty)
        {
            YourDatagridview.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }

и вуаля !!

1

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

Просто обратите внимание, что для CheckBoxCell это событие срабатывает до того, как значение флажка действительно изменится. Это означает, что независимо от того, что вы делаете с текущей ячейкой, она будет переопределена событиями, которые запускаются позже. Поведение, которое вытряхнет из этого, заключается в том, что вы не можете проверять ни одну из ячеек в строке, отметив один флажок в строке и затем проверяя его снова (пытаетесь ли вы установить значение флажка в обработчике или нет, флажок будет сброшен после второго щелчка). Чтобы преодолеть это и заставить один из флажков быть отмеченным, вы можете вместо этого обработать CellValueChanged, и если измененная ячейка является текущей и не отмечена, отметьте ее.

спасибо, что разобрался. Cheeso
& quot; вместо этого вы можете обрабатывать CellValueChanged, и если измененная ячейка является текущей и не отмечена, отметьте ее & quot; Как предотвратить переполнение стека? Можете ли вы добавить пример кода?
7

Когда я посмотрел в документе дляCellValueChangedЯ нашел этот полезный бит:

The DataGridView.CellValueChanged event occurs when the user-specified value is committed, which typically occurs when focus leaves the cell.

In the case of check box cells, however, you will typically want to handle the change immediately. To commit the change when the cell is clicked, you must handle the DataGridView.CurrentCellDirtyStateChanged event. In the handler, if the current cell is a check box cell, call the DataGridView.CommitEdit method and pass in the Commit value.

Это код, который я использовал для определения поведения радио:

    void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
    {
        // Manually raise the CellValueChanged event
        // by calling the CommitEdit method.
        if (dataGridView1.IsCurrentCellDirty)
        {
            dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
        }
    }

    public void dataGridView1_CellValueChanged(object sender,
                                               DataGridViewCellEventArgs e)
    {
        // If a check box cell is clicked, this event handler sets the value
        // of a few other checkboxes in the same row as the clicked cell.
        if (e.RowIndex < 0) return; // row is sometimes negative?
        int ix = e.ColumnIndex;
        if (ix>=1 && ix<=3)
        {
            var row = dataGridView1.Rows[e.RowIndex];

            DataGridViewCheckBoxCell checkCell =
                (DataGridViewCheckBoxCell) row.Cells[ix];

            bool isChecked = (Boolean)checkCell.Value;
            if (isChecked)
            {
                // Only turn off other checkboxes if this one is ON. 
                // It's ok for all of them to be OFF simultaneously.
                for (int i=1; i <= 3; i++)
                {
                    if (i != ix)
                    {
                        ((DataGridViewCheckBoxCell) row.Cells[i]).Value = false;
                    }
                }
            }
            dataGridView1.Invalidate();
        }
    }
Большое спасибо за этот пост;)

Похожие вопросы