I have a dataGridView1
, dataGridView2
and a ButtonAdd
in one Form.
The user will:
1- select any one "Cell" or the "entire Row".
2-select multiple Rows
Then:
the data selected will be moved from dataGridView1 to dataGridView2 when the button clicked. that's all what i need to do.
My try:
I have tried this solution after many searches and it's almost done but there's a little problem I couldn't handle:
Full Code:
private const string strconneciton = @"YourConnectionString";
SqlConnection con = new SqlConnection(strconneciton);
SqlCommand cmd = new SqlCommand();
DataTable dataTable;
private void loadDataIntoGridView1()
{
try
{
con.Open();
cmd.CommandText = "SELECT id, accNum, accName FROM Employees";
cmd.Connection = con;
SqlDataAdapter adapter = new SqlDataAdapter();
adapter.SelectCommand = cmd;
dataTable = new DataTable();
adapter.Fill(dataTable);
BindingSource bSource = new BindingSource();
bSource.DataSource = dataTable;
dataGridView1.DataSource = bSource;
//i don't know if this line is useful...
dataGridView2.DataSource = dataTable.Clone();
adapter.Update(dataTable);
con.Close();
}
catch (Exception ed)
{
con.Close();
MessageBox.Show(ed.Message);
}
}//end loadDataIntoGridView1
private void buttonSend_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedCells.Count > 0)
{
foreach (DataGridViewCell oneCell in dataGridView1.SelectedCells)
{
if (oneCell.Selected)
{
//this should add the rows that is selected from dataGridView1 and,
//pass it to dataGridView2
var currentRow = ((DataRowView)dataGridView1.CurrentRow.DataBoundItem).Row;
((DataTable)dataGridView2.DataSource).ImportRow(currentRow);
//this will remove the rows you have selected from dataGridView1
dataGridView1.Rows.RemoveAt(oneCell.RowIndex);
}//end if
}//end foreach
}//end if
}//end button click
Lets Debug:
just Note a one thing before starting:
- the method for deleting rows (multi or single) is working fine in all cases.
- the method for adding to the DGV2 is the problem, I had taken it from here ...it works fine when selecting a single row but not multiple.
1- if you have selected a one cell/row it will be added and removed successfully.
2- if you have selected a multiple rows lets say the first and the second it will add the second and the third, then definitely will deleted them, but only one is added.. why?!
Because here
var currentRow = ((DataRowView)dataGridView1.CurrentRow.DataBoundItem).Row;
((DataTable)dataGridView2.DataSource).ImportRow(currentRow);
gets the current index of the existing rows in the DGV1 and iterate to the number of the selecting rows and add them to DGV2.
Screenshot:
image of how the process is done: .
What should be done to solve this problem?
Here's a complete snippet that does it. In this sample I am using 2
BindingList
to achieve your requirements. Upon the user clicking the button, the sample will copy the selected items fromdgv1data
todgv2data
. Then it will remove the items fromdgv1data
.Although marco has a point, ownership of the row is to the table as exception thrown. To bypass this, you might want to do this way...
// creates a new row based on the table you are about to // insert INTO with same structure
The ItemArray is a list of ALL the column properties of the table in order without explicit reference to Row["someColumn"]. So copying the array to the new row gets you all the columns. This is - provided both table structures are the same - and appears to be from your scenario provided.
Clarification
The above code only does a single row and would be applied based on your loop where the
You have multiple columns selected per row thus causing some confusion to your loops. You are actually hitting the same row multiple times. In any event, i found you are actually doing this in a Windows Application, not WPF.. I have created a form and posting the code below.
Here, I have a form with the two grids similar to what you had and a single button to "Move" the records (but only one direction), you will have to adjust for one / all / from / to directions.
A few changes. I changed the grid to force selection mode to the entire ROW. This will prevent multiple entries for a single row just because you have multiple columns available. Multi-selection is still possible by dragging between cells OR Ctrl+Click on individual rows. This allows for selecting rows not within the same viewable screen region.
I also just did a create table to force simulating 20 rows of data to force not all rows visible at the same time.
Next the click event... If no ROWS selected, get out... If there ARE, cycle through, but this does ONE PER ROW instead of multiple times if multiple columns. Get the binding data row, import and remove...
You were very close otherwise and did not need the copy-array. I think the overall problem was that of your columns mode selection hitting the same record multiple times. After the remove-at of row 0 for the first cell, row 1 became row 0 and thus copied that, removed and you are now out of a list as there is only one record left to process. Here, we are getting the entire row ONCE, regardless of the column within it selected.
Instead of
use something like this:
Let me know if that works!