James Morrish
James Morrish

Reputation: 475

Unable to set Row.Readonly=false with databound DataGridView

I have a dataGridView that is bound to a tableAdaptor, behind this table is a MS SQL server database.

In Form1_Load i have dataGridView1.ReadOnly = true; and in the dataGridView1 controls on the form i have Enable Editing selected.

![Showing the controls set

I then fill the dataGridView at run time here: stockTableAdapter.Fill(sIMSDataSet.Stock);

What i am trying to do, is have a user select any cell within a row and click a button which then allows the user to edit that row.

I have tried various ways to get the row the user currently has selected to be set to ReadOnly=flase but i can't get it to work.

This is what i have tried:

  private void button7_Click_1(object sender, EventArgs e)
        {
            if (dataGridView1.CurrentRow.ReadOnly == true)
            {
                dataGridView1.CurrentRow.ReadOnly = false;
                dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;
            }
        }

And i have also tried the answer is this question:

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

The user suggests in his testing he was not able to set the row to ReadOnly=flase on databound dataGridViews. But seeing as the answer is now 6 years old i was hoping there was a way to do it now.

Upvotes: 0

Views: 623

Answers (1)

JohnG
JohnG

Reputation: 9479

Your question is somewhat confusing in a sense that it is unclear how the grid is initially set up. Looking at the link to the previous question, I am not sure “why” a data bound grid would make a difference. From an overall perspective, it appears odd to make individual rows read only. In other words, if the grid is read only when the form loads, then ALL rows are read only regardless of the data source.

Therefore, instead of setting an “individual” row to read only, I am guessing it “may” be easier to simply set the “whole” grid to read only. This will work if you wire up the grids RowLeave event as the link does.

Example, the whole grid is read only and the user cannot make changes to the cells, the user then clicks the “Edit” button in one of the rows. When this happens, we set the row color for that row the clicked “edit” button is in to visually show the user that the row is ready to edit. Then set the grids read only property to false. Obviously, this is going to allow the user to “edit” ANY cell in the grid at this point, however, wiring up the grids RowLeave event will prevent this if we set the grids read only property back to true.

The code for this is relatively straight forward... Note: the InEditMode1 variable is used to know if a row is being edited and to avoid unnecessarily re-setting the grids read only property when no row is currently being edited.

private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
  if (dataGridView1.Columns[e.ColumnIndex].Name == "Edit") {
    dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.GreenYellow;
    dataGridView1.ReadOnly = false;
    InEditMode1 = true;
  }
}

private void dataGridView1_RowLeave(object sender, DataGridViewCellEventArgs e) {
  if (InEditMode1) {
    dataGridView1.ReadOnly = true;
    dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.White;
    InEditMode1 = false;
  }
}

Dropping a grid onto a new form and using the code below to add the columns and some data should allow for the testing of this.

public void CreateDataGridView() {
  dataGridView1.Columns.Add("Id", "Id");
  dataGridView1.Columns.Add("Lastname", "Lastname");
  dataGridView1.Columns.Add("City", "City");
  dataGridView1.Columns.Add(GetBtnColumn());
  dataGridView1.Rows.Add("1", "Muller", "Seattle");
  dataGridView1.Rows.Add("2", "Arkan", "Austin");
  dataGridView1.Rows.Add( "3", "Cooper", "New York");
}

Next is an example using a DataSource for the grid. In this example a DataTable is used as a DataSource to the grid. In addition, the “Edit” Button column is added AFTER the grids DataSource has been set. The forms load event may look like below…

private void Form2_Load(object sender, EventArgs e) {
  DataTable GridTable = GetDataTable();
  FillDataTable(GridTable);
  dataGridView2.DataSource = GridTable;
  dataGridView2.Columns.Add(GetBtnColumn());
}

For testing…

public DataTable GetDataTable() {
  DataTable dt = new DataTable();
  dt.Columns.Add("Id", typeof(string));
  dt.Columns.Add("LastName", typeof(string));
  dt.Columns.Add("City", typeof(string));
  return dt;
}

private void FillDataTable(DataTable dt) {
  dt.Rows.Add("1", "Muller", "Seattle");
  dt.Rows.Add("2", "Arkan", "Austin");
  dt.Rows.Add("3", "Cooper", "New York");
}

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

Note the code for this is the same code in the NON-DataBound grid above.

private void dataGridView2_CellClick(object sender, DataGridViewCellEventArgs e) {
  if (dataGridView2.Columns[e.ColumnIndex].Name == "Edit") {
    dataGridView2.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.GreenYellow;
    dataGridView2.ReadOnly = false;
    InEditMode2 = true;
  }
}

private void dataGridView2_RowLeave(object sender, DataGridViewCellEventArgs e) {
  if (InEditMode2) {
    dataGridView2.ReadOnly = true;
    dataGridView2.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.White;
    InEditMode2 = false;
  }
}

I hope this will help.

Upvotes: 1

Related Questions