|
-
Jan 21st, 2009, 11:47 PM
#1
Conditional Read-Only Columns in DataGridView
VB version here.
A couple of people have asked a similar questions recently so I thought I'd post the advice I provided here as it may help others too. The first person asked how to retrieve data from a database and display it in a DataGridView without the user being able to edit the data in certain columns, while still allowing the user to enter data into that column for new records and also edit that column for records that have been previously added in the current session. Here's the code I provided:
Code:
private void Form1_Load(object sender, EventArgs e)
{
DataTable table = new DataTable();
table.Columns.Add("ID", typeof(int)).AutoIncrement = true;
table.Columns.Add("Name", typeof(string));
table.Rows.Add(null, "Peter");
table.Rows.Add(null, "Paul");
table.Rows.Add(null, "Mary");
/* Set all RowStates to Unchanged, as they would be
* if the data had been retrieved from a database. */
table.AcceptChanges();
// Bind the data to the grid through the BindingSource.
this.bindingSource1.DataSource = table;
this.dataGridView1.DataSource = this.bindingSource1;
// Make the Name column read-only by default.
this.dataGridView1.Columns[1].ReadOnly = true;
}
private void bindingSource1_CurrentChanged(object sender, EventArgs e)
{
// Make sure the grid has columns, which it won't when the BindingSource is first bound.
if (this.dataGridView1.ColumnCount > 0)
{
// Get the underlying DataRow that corresponds to the selected row in the grid.
DataRow row = ((DataRowView)this.bindingSource1.Current).Row;
/* Only allow editing if the row is detached (created but not yet added to the table)
* or added (added to the table since the last AcceptChanges call). */
this.dataGridView1.Columns[1].ReadOnly = !(row.RowState == DataRowState.Detached ||
row.RowState == DataRowState.Added);
}
}
That code assumes that you've added a DataGridView and a BindingSource to your form. You'll also have to wire up the event handlers.
Note that, when the user selects a row in the grid, the CurrentChanged event of the BindingSource is raised. The code gets the underlying DataRow and only allows the second column to be edited if that row has a RowState of Detached or Added. Detached corresponds to the last row in the grid. When the user starts adding data there it creates a new DataRow but it doesn't get added to the DataTable until you navigate away from that row. As soon as you navigate away from that row the DataRow gets added to the DataTable and its RowState becomes Added.
Someone else asked how to disable editing in all but the last row. The answer was to remove the test for a RowState of Added and just test for Detached. It's worth noting, though, that, if you do that, the user won't be able to change the data in new rows once they've added them if they realise they've entered the wrong value.
Last edited by jmcilhinney; Jan 21st, 2009 at 11:54 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|