Tung Pham
Tung Pham

Reputation: 599

unable to set Row.Readonly=false in Datagridview in winforms

I have a datagridview with its ReadOnly set true to prevent people editing.

then I have a button on each row. when I click on a specific button, I wrote:

private void DGGrade_CellClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.RowIndex > 0 && e.ColumnIndex == DGGrade.Columns["Edit"].Index)
        {

            DGGrade.Rows[DGGrade.CurrentCell.RowIndex].ReadOnly = false;

            DGGrade.Rows[DGGrade.CurrentCell.RowIndex].DefaultCellStyle.BackColor = Color.White;
        }

But it is not working. please help

Upvotes: 1

Views: 2631

Answers (1)

surfmuggle
surfmuggle

Reputation: 5954

I do not know the reason why it is not working but as far as i can tell from my test runs it has to deal how the data is bound. If you use dataGridView1.DataSource = GetDataSource(); then it did not work in my tests. I have read once about some of the drawbacks of automated binding but i could not find it. Here is the code that works. A row is only in EditMode after the User has clicked the button Edit in the corresponding row. I will be back later - let me know if you need more pointers.

public partial class Form1 : Form
{
    int rowIndexOfEditableRow = -1;
    public Form1() {
       InitializeComponent();           
       CreateDataGridView(dataGridView1);
       SetExistingDataGridViewRowsReadOnly();           
       this.dataGridView1.Columns.Add(GetBtnColumn());          
    }

    private void SetExistingDataGridViewRowsReadOnly() {
        DataGridViewRowCollection rows = this.dataGridView1.Rows;
        foreach (DataGridViewRow row in rows) {
            row.ReadOnly = true;
        }
    }

It seems that the grid must be filled manually - at least this way the change of ReadOnly works

public void CreateDataGridView(DataGridView dgv) 
{                   
   dgv.ColumnCount = 3;
   dgv.Columns[0].Name = "Id";
   dgv.Columns[1].Name = "Lastname";
   dgv.Columns[2].Name = "City";
   dgv.BackgroundColor = Color.Gray;                        
   AddRowsToDataGridView(dgv);          
}


private void AddRowsToDataGridView(DataGridView dgv)
{
  string[] row1 = new string[]{"1", "Muller", "Seattle"};
  string[] row2 = new string[]{"2", "Arkan", "Austin"};
  string[] row3 = new string[]{"3", "Cooper", "New York"};        
  object[] rows = new object[] { row1, row2, row3 };

  foreach (string[] rowArray in rows)
  {
    dgv.Rows.Add(rowArray);
  }
}

Helper method to create a column with a button

    public DataGridViewButtonColumn GetBtnColumn()
    {       
      DataGridViewButtonColumn btnColumn = new DataGridViewButtonColumn();
      btnColumn.HeaderText = "Edit";
      btnColumn.Text = "Edit";
      btnColumn.UseColumnTextForButtonValue = true;            
      return btnColumn;
    }

Event handler checks if the user has clicked the edit button. In this case the current row will be set to ReadOnly = false. This allows that the user to edit the row. To emphasize it i changed the background color of the row.

    private void DataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) 
    {
      int colIndex = e.ColumnIndex;
      int rowIndex = e.RowIndex;
      Type cellType =   dataGridView1.Columns[colIndex].CellType;
      if (cellType == typeof(DataGridViewButtonCell))               
      {
        dataGridView1.Rows[rowIndex].ReadOnly = false;
        dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.GreenYellow;
        this.rowIndexOfEditableRow = rowIndex;
        label1.Text = rowIndexOfEditableRow.ToString() + " " + colIndex.ToString();
      }             
    }

If the Row-leave-Event is fired the style is reset and the global parameter which row is editable is set to the initial value

    private void DataGridView1_RowLeave(object sender, DataGridViewCellEventArgs e) 
    {
      int rowIndex = e.RowIndex;
      dataGridView1.Rows[rowIndex].ReadOnly = true;
      dataGridView1.Rows[rowIndex].DefaultCellStyle.BackColor = Color.White;
      this.rowIndexOfEditableRow = -1;
    }
}

The above code contains all (except the designer files) that you need to create this demo:

enter image description here

Upvotes: 2

Related Questions