Reputation: 1988
Could somebody advice how to do this?
Currently i have :
The issue is : when i try to edit second field (Text2) the first one (Text1) loses the focus, exits edit mode and saves changes that i made meanwhile i want to save all changes in a row simultaneously.
What i want to implement :
The question is : how to keep all cells in a row in edit mode until i press specific button?
Upvotes: 2
Views: 5046
Reputation: 1988
Ok, i know it may look a bit messy but this seems to be simplest solution i could come up to - display TextBox over each read only cell when grid is going to edit mode :
public void DisplayEditors(DataGridView grid, DataGridViewRow row)
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.ReadOnly == false)
{
var place = grid.GetCellDisplayRectangle(cell.ColumnIndex, cell.RowIndex, true);
var name = string.Format("EDITOR-{0}-{1}", cell.ColumnIndex, cell.RowIndex);
var editor = grid.Controls.Find(name, false).FirstOrDefault();
if (editor == null)
{
editor = new TextBox();
(editor as TextBox).Name = name;
grid.Controls.Add(editor);
}
else
{
editor.Show();
}
editor.Size = place.Size;
editor.Location = place.Location;
editor.Text = Convert.ToString(cell.Value);
}
}
}
Upvotes: 0
Reputation: 66
Maybe you can use a custom DataGridView like this
public class CustomDGV : DataGridView
{
private object _cellValue;
private Dictionary<int, object[]> _pendingChanges;
public CustomDGV()
{
_pendingChanges = new Dictionary<int, object[]>();
}
protected override void OnCellBeginEdit(DataGridViewCellCancelEventArgs e)
{
// Save the value of the cell before edit
_cellValue = this[e.ColumnIndex, e.RowIndex].Value;
// If there's already a pending change for that cell, display the edited value
if (_pendingChanges.ContainsKey(e.RowIndex))
{
this[e.ColumnIndex, e.RowIndex].Value = _pendingChanges[e.RowIndex][e.ColumnIndex];
}
base.OnCellBeginEdit(e);
}
protected override void OnCellEndEdit(DataGridViewCellEventArgs e)
{
// Adds the edited value of the cell into a dictionary
if (!_pendingChanges.ContainsKey(e.RowIndex))
{
_pendingChanges.Add(e.RowIndex, new object[this.ColumnCount]);
}
_pendingChanges[e.RowIndex][e.ColumnIndex] = this[e.ColumnIndex, e.RowIndex].Value;
// Display the "old" value
this[e.ColumnIndex, e.RowIndex].Value = _cellValue;
}
public void SavePendingChanges(int rowIndex)
{
if (_pendingChanges.ContainsKey(rowIndex))
{
// Gets the pending changes for that row
var rowData = _pendingChanges[rowIndex];
// Update every cell that's been edited
for(int i = 0; i < rowData.Length; i++)
{
if (rowData[i] != null)
this[i, rowIndex].Value = rowData[i];
}
// Removes the pending changes from the dictionary once it's saved
_pendingChanges.Remove(rowIndex);
}
}
}
And on CellContentClick you can call SavePendingChanges()
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex > -1 && e.RowIndex > -1)
{
if (e.ColumnIndex == 3) // Save button
{
dataGridView1.SavePendingChanges(e.RowIndex);
}
}
}
Upvotes: 2