Programmatically updating selected rows misses the last one in dgv.DataSource.GetChanges()? - c#

I have a data grid view with a column (combobox column). The following function has been implemented.
Select several rows (click the left most row header and drag).
Programmingly set the value to something (see following). All the selected rows changes.
foreach (DataGridViewRow item in dgv.SelectedRows)
{
item.Cells["cbxxxxx"].Value = p;
}
dgv.EndEdit();
Click the save button to save the changes. However, the last row is excluded in the (dgv.DataSource as DataTable).GetChanges(). The count of the changed data table is always one less than the selected rows. The missing row is the last one (with the black triangle).
How to fix the problem?

The last row presumably is still the active row, so you need to end the edit through the BindingContext:
foreach (DataGridViewRow item in dgv.SelectedRows) {
item.Cells["cbxxxxx"].Value = p;
}
this.BindingContext[dgv.DataSource].EndCurrentEdit();

Related

C# DATAGRIDVIEW select rows and display selected rows

My datagrid view is populated with multiple rows of data, I want to be able to select multiple rows in my datagridview and then update the datagridview to only display the selected rows but i am getting errors
public void btnUpdate_Click(object sender, EventArgs e)
{
List<DataGridViewRow> rowCollection = new List<DataGridViewRow>();
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
rowCollection.Add(dataGridView1.Rows[row.Index]);
}
//dataGridView1.Rows.Clear();
data.Tables[0].Clear();
foreach (DataGridViewRow row in rowCollection)
{
DataRow r = data.Tables[table].NewRow();
dataGridView1.Rows.Add(row);
//write the data in the DataRow and then add the datarow in your datatable
data.Tables[table].Rows.Add(r);
}
CreateGraph(zedGraphControl1);
}
When i select the rows and click the update button i am getting the error
"Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound."
row {DataGridViewRow { Index=-1 }} System.Windows.Forms.DataGridViewRow
I have tried looking at the exception help for this but cannot make sense of it
Thanks for your help
If I remember correctly the datagridview must not be data bound in order to manipulate the rows.
I believe that I solved this problem a couple months back but I can't get access to my projects right now.
I think you can do it by finding and removing the rows from the data source and then refresh the datagridview
(personal advice: take a short break 10-15 mins and go back at it with a clearer mind)

winform multiple select grid row and get row index of selected rows

I have a databound gridview in my winform. I want to know how to get the index of Currently selected rows i.e multiple rows.
I am able to do this with a single row. but is there a way I can have a checkbox or something in which I can index of multiple rows.
The Image below will help u understand better of my requirement.
First set CellContentClick event to your DataGridView.
dataGridView.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.onCellContentClick);
For every cell click it will invoke the following method. Here you can create a list and populate it with clicked row index.
public void onCellContentClick(DataGridViewCellEventArgs cell)
{
// Check whether selected cell is check box column, here 0 indicates the check box column.
if (cell.ColumnIndex == 0)
{
bool isChecked = (Boolean) dataGridView[cell.ColumnIndex, cell.RowIndex].EditedFormattedValue;
if(isChecked)
{
// Below will give you the selected cell row index, for multiple rows you can populate those index in list or whatever you convenient with.
cell.RowIndex;
}
}
}
Use DataGridView.SelectedRows property to get all selected rows.
To select multiple rows:
DataGridView.MultiSelect = true;

Selection Start Row in DatagridView

I am using the windows DataGridView, in this grid i allowed the multiple rows selection.
When i am checking the dataGridView1.SelectedRows[0].Index it's giving last selected rows Index. Just i want from which row the selection started(Start Row).
You can try with this code
Int32 selectedRowCount =
dataGridView1.Rows.GetRowCount(DataGridViewElementStates.Selected);
dataGridView1.SelectedRows[selectedRowCount - 1 ].Index.ToString();
you can use foreach loop to check the lowest indexed Row.
Because Rows in SelectedRows collection are added in order as you select the row.
Here is complete foreach loop..
int i=int.MaxValue;
foreach (DataGridViewRow rw in dataGridView1.SelectedRows)
{
if (rw.Index < i)
{
i = rw.Index;
}
}
DataGridViewRow r = dataGridView1.Rows[i];
it will return you lowest indexed selected row.
You can try with something like
dataGridView1.SelectedRows[dataGridView1.SelectedRows.Count - 1].Index
But from my point of view, the selection order in the SelectedRows is not something that should be relied on anyway. As far as I know, the documentation doesn't specify any particular order... You should do something by yourself if that's important for your application.

Delete a Row from a DataGridView given its index

My DataGridView is a single line selection and theres a rowEnter Event where I get the line index every time the selected line changes.
private void rowEnter(object sender, DataGridViewCellEventArgs e)
{
currentRowIndex = e.RowIndex;
}
when I press a delete button I use the same index to delete the row
myDataSet.Avaliado.Rows[currentRowIndex].Delete();
avaliadoTableAdapter.Update(myDataSet.Avaliado);
it works fine if no column in the DataGridView is sorted, otherwise a get an error. What should be the way to know the row index in the dataset that corresponds to the rowindex from the DataGridView?
You don't need to be grabbing the current row index every time a new row is selected. Try something like this instead:
if (_Grid.SelectedRows.Count <= 0) { return; } // nothing selected
DataGridViewRow dgvRow = _Grid.SelectedRows[0];
// assuming you have a DataTable bound to the DataGridView:
DataRowView row = (DataRowView)dgvRow.DataBoundItem;
// now go about deleting the row however you would do that.
If you've got some other sort of data type bound to each row of the grid, simply cast the DataGridViewRow.DataBoundItem to whatever your data type is.
You can find the currently selected row at the time that you are doing the delete:
if(myDataGridView.SelectedRows.Count > 0)
currentRowIndex = myDataGridView.SelectedRows[0].Index;
I usually have the Primary Key for that row as a hidden column (my convention is using the first using column).
I can then ask my persistence Layer to do the rest.

Deleting multiple rows in an unbound datagridview

I have a project that reads rows from an SQL database and displays them in a datagridview. That part works great. I want to show a subset of these records by deleting every non selected row in the grid. This is the code:
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (!row.Selected)
{
if (!row.IsNewRow)
{
dataGridView1.Rows.Remove(row);
//dataGridView1.Rows.Remove(dataGridView1.CurrentRow);
}
}
}
It either deletes from the bottom up to the selected area and leaves the unselected rows above, or deletes selected as well as unselected rows.
Could anyone point me in the right direction?
The rows are being altered as others are being removed, so some elements are getting skipped incorrectly.
You could use 2 loops: the 1st to invert the selected items, and the 2nd to delete selected items (which would be the previously unselected items prior to inversion).
foreach (DataGridViewRow row in dataGridView1.Rows)
{
// invert row selections
if (!row.Selected)
{
if (!row.IsNewRow)
{
row.Selected = true;
}
}
else
{
row.Selected = false;
}
}
// remove selected rows
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
dataGridView1.Rows.Remove(row);
}

Categories