Datagrid in delete the row - c#

I am using delete row index to delete a row in datagridview.
But when one row is deleted then datagridview automatically appends next row
first time any index is deleted then itscorrect but at the second time row-1 indexed row is deleted
I am using this code:
for (int i = 0; i < path.Length; i++)
{
lpath.Add(path[i].ToString());
dataGridView1.Rows.RemoveAt(int.Parse(arr[i]));
}

you have to reduce the 'i' after you delete a row when using for loop
See the following code
for (int i = 0; i < path.Length; i++)
{
lpath.Add(path[i].ToString());
dataGridView1.Rows.RemoveAt(int.Parse(arr[i]));
i--; }

As i see it you skew the index off the dataGridView1 the first time.
lets say you have a list with element {1,2,3,4,5} if we now remove index 3 and then 4 we the end up removing 3 and 5 giving us the list {1,2,4} but we wanted to remove 3 and 4 not 3 and 5
what i think you want to do is to get all indexes you want to remove, and the order them and remove from top to bottom so instead of removing 3 an 4 in that order you remove 4 and 3 giving us the list {1,2,5}
List<int> RemoveList = new List<int>();
for (int i = 0; i < path.Length; i++)
{
lpath.Add(path[i].ToString());
RemoveList.Add(int.Parse(arr[i]));
}
//Remove highest index first.
RemoveList.OrderByDescending(a=>a);
for (int i = 0; i < RemoveList.Count; i++)
{
dataGridView1.Rows.RemoveAt(RemoveList[i]);
}

it's a bit weird to increase i within the for loop than decrease it. Why don't you add the items than clear all rows ?
for (int i = 0; i < path.Length; i++) {
lpath.Add(path[i].ToString());
}
dataGridView1.Rows.Clear();

Related

How can I print the following pattern with the for statement?

How can I print the following pattern with the for statement?
AAAA
AAAB
AABB
ABBB
BBBB
What I tried to do:
Code:
int stars = 4;
for (int row = stars; row >= 1; row--)
{
for (int i = 0; i < row; i++)
{
Console.Write("A");
}
Console.WriteLine();
}
You where almost there.
I made a small change in the first for loop to add another row (>= 1 to >= 0). We need 5 rows for 4 stars, 6 rows for 5 stars, etc.
Compared the second for loop to stars as well because we want 4 values on each row (when stars is 4).
Added an if statement to check if we need to write an A or B based on the iteration number of both loops.
See code below:
int stars = 4;
for(int i = stars; i >= 0; i--) {
for(int j = 0; j < stars; j++) {
if(i > j) {
Console.Write('A');
}
else {
Console.Write('B');
}
}
Console.WriteLine();
}

If dataGridView value is not null then XX not working as intended

Inside a button click I have this code which inserts the text from a combobox into column C:
private void updateExcel_Click(object sender, EventArgs e)
{
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
if (dataGridView1.Rows[i].Cells[j].Value != null)
{
for (int ii = 0; ii < dataGridView1.RowCount - 1; ii++)
{
dataGridView1[2, ii].Value = ConsigneeCombo.Text;
}
break;
}
}
}
}
When its ran it should only put the value on rows with a value in column A of the row, but it is repeating the value inserted on all rows.
The posted loop and the logic do not look correct in reference to what you what to do….
… ”it should only put the value on rows with a value in column A of
the row” ….
Currently the code, uses one for loop to loop through all the “rows” in the grid...
for (int i = 0; i < dataGridView1.Rows.Count; i++)
Then another for loop to loop through all the “columns” in the grid…
for (int j = 0; j < dataGridView1.Columns.Count; j++)
This is going to loop through ALL the cells in the grid…
IF One of the cells in the grid is NOT null …
if (dataGridView1.Rows[i].Cells[j].Value != null)
Then (AGAIN?) loop through ALL the "rows" and set the third columns value in that row to the value contained in the combo box…. ?
This doesn’t sound like what you want. The “break” statement is simply going to skip the columns “after” the “first” value is found. This logic is not going to achieve what you are asking.
Therefore, to simplify
”it should only put the value on rows with a value in column A of the row”
This implies we only need to loop through all the rows. It is not necessary to loop through the columns and we only need to do this loop once. Logic being…
Loop through all the rows, in each row, if there is a “value” in column A (0), then add the combo box text to column C (2). This logic may look something like below.
private void updateExcel_Click(object sender, EventArgs e) {
for (int i = 0; i < dataGridView1.RowCount; i++) {
if (!dataGridView1.Rows[i].IsNewRow &&
dataGridView1.Rows[i].Cells[0].Value != null &&
dataGridView1.Rows[i].Cells[0].Value.ToString() != "") {
dataGridView1[2, i].Value = ConsigneeCombo.Text;
}
}
}
This will only add the combo box text to the third column if the value in the first column is NOT empty.

How to delete one row and update a certain cell in the rest?

What I want to do is if I click a delete button, the whole row will be deleted (e.g Row 1). And then, when it is deleted, the remaining rows will update it's "ID" prior to the value of the deleted row.
For example, I delete Row 1, Row2's ID will become 1 and Row 3's ID will become 2.
Here's what I tried so far:
private void btn_Delete_Click(object sender, EventArgs e)
{
string type = (string)dgv_Layers.CurrentRow.Cells[1].Value;
int index = (int)dgv_Layers.CurrentRow.Cells[0].Value;
//MessageBox.Show(index.ToString());
if(type == "R")
{
index--;
//draw._rectangles.RemoveAt(index);
dgv_Layers.Rows.RemoveAt(index);
counter--;
for(int i =0; i < dgv_Layers.Rows.Count; i++)
{
index++;
dgv_Layers.Rows[i].Cells[0].Value = index;
}
}
}
UPDATE
Updated the code. Did the part where I can delete the topmost part and update the remaining rows. My problem now is when I delete in between, e.g. Row 3, the rows updates and the IDs starts from 3. I want it to start from 1;
Its because you are using value of index which is already 3.
int index = (int)dgv_Layers.CurrentRow.Cells[0].Value; //index=3, when you delete 3rd row
and then in your loop you are doing like this -
if(type == "R")
{
index--; //2
//draw._rectangles.RemoveAt(index);
dgv_Layers.Rows.RemoveAt(index);
counter--;
for(int i =0; i < dgv_Layers.Rows.Count; i++)
{
index++; //3
dgv_Layers.Rows[i].Cells[0].Value = index; //3
}
}
No need of using index's value here. you should be using this loop like this -
for(int i =0; i < dgv_Layers.Rows.Count; i++)
{
dgv_Layers.Rows[i].Cells[0].Value = i+1;
}
This will start values from 1.
or you can do it like this -
for( ; index< dgv_Layers.Rows.Count; index++)
{
dgv_Layers.Rows[index].Cells[0].Value = index+1;
}

Create 2D array from datatable

I am trying to create a 2D array from a DataTable, however Instead of getting the end result defined below. One row is not added, if that row is added, it will overwrite the column values.
Here is the end result I am looking to get:
[
//columns
['TaskID','TaskName','StartDate','EndDate','Duration','PercentComplete','Dependecies'],
//rows
['Cite','Create bibliography',null,1420649776903,1,20,'Research'], //missing row
['Complete','Hand in paper',null,1420908976903,1,0,'Cite,Write'],
['Outline','Outline paper',null,1420563376903,1,100,'Research'],
['Research','Find sources',1420390576903,1420476976903,null,100,null],
['Write','Write paper',null,1420822576903,3,25,'Research,Outline']
];
However, I get this.
[
["TaskID","TaskName","StartDate","EndDate","Duration","PercentComplete","Dependecies"],
["Complete","Hand in paper",null,1420908976903.0,1,0,"Cite,Write"],
["Outline","Outline paper",null,1420563376903.0,1,100,"Research"],
["Research","Find sources",1420390576903.0,1420476976903.0,null,100,null],
["Write","Write paper",null,1420822576903.0,3,25,"Research,Outline"]
]
I have tried:
// define the array size based on the datatable
object[,] multiDimensionalArry = new Object[breDataTable.Rows.Count, breDataTable.Columns.Count];
const int columnsArryIndex = 0;
// populate array with column names
if (breDataTable.Columns.Count > 0 && breDataTable.Rows.Count > 0)
{
// loop around columns
for (int i = 0; i <= breDataTable.Columns.Count - 1; i++)
{
// add all the column names
multiDimensionalArry[columnsArryIndex, i] = breDataTable.Columns[i].ColumnName;
}
}
// outer loop - loop backwards from the bottom to the top
// we want to exit the loop, when index == 0 as that is reserved for column names
for (int j = breDataTable.Rows.Count - 1; j >= 0; j--)
{
// get current row items array to loop through
var rowItem = breDataTable.Rows[j].ItemArray;
// inner loop - loop through current row items, and add to resulting multi dimensional array
for (int k = 0; k <= rowItem.Length - 1; k++)
{
multiDimensionalArry[j, k] = rowItem[k];
}
}
You're missing one row when creating your array since the columns name row dosent count as a row
object[,] multiDimensionalArry = new Object[breDataTable.Rows.Count + 1, breDataTable.Columns.Count];
And you need to change your for loop to take into count the extra row
// outer loop - loop backwards from the bottom to the top
// we want to exit the loop, when index == 0 as that is reserved for column names
for (int j = breDataTable.Rows.Count - 1; j >= 0; j--)
{
// get current row items array to loop through
var rowItem = breDataTable.Rows[j].ItemArray;
// inner loop - loop through current row items, and add to resulting multi dimensional array
for (int k = 0; k <= rowItem.Length - 1; k++)
{
multiDimensionalArry[j + 1, k] = rowItem[k];
}
}

Looping through each element in a DataRow

Basically, I have a DataTable as below:
I want to run a method per element per row which has the parameters
AddProductPrice(SKU, Price, PriceBracket)
As an example...:
If we take the first row of data, the method will be run a potential of 16 times, once for each time Total Price X isn't null.
So for the first total price in the first row the call will be:
AddProductPrice(SKU, <Total Price 1 value>, 1)
Then for the second total price in the first row the call will be:
AddProductPrice(SKU, <Total Price 2 value>, 2)
Please note: for the National Selling element the call would be:
AddProductPrice(SKU, <National Selling value>, 16)
Is there a clever way to loop through each element in a DataRow to make the procedure more efficient?
For each row, looping through the columns and then finding the index of "Total Price", "National Selling" and adding product price accordingly.
for (int i = 0; i < dataTable.Rows.Count; i++)
{
DataRow myRow = dataTable.Rows[i];
for (int j = 0; j < dataTable.Columns.Count; j++)
{
if (dataTable.Columns[j].ColumnName.IndexOf("Total Price") > 0)
{
AddProductPrice(SKU, myRow.ItemArray[j], j);
}
else if (dataTable.Columns[j].ColumnName.IndexOf("National Selling") > 0)
{
AddProductPrice(SKU, myRow.ItemArray[j], 16); //
}
}
}
Loop through the DataTable.Columns Collection and parse based on the Column Name.
for(int i=0;i < dt.Columns.Count; i++)
{
if (dt.Columns[i].ColumnName.StartsWith("Total Price"))
{
var curBracket = Convert.ToInt32(dt.Columns[i].ColumnName.SubString(11));
AddProductPrice(SKU, curRow[dt.Columns[i].ColumnName, curBracket);
}
}
You can use the ItemArray (type object[]) property of DataRow and iterate through its elements from column tab.Columns.IndexOf("Trade Price 1") to tab.Columns.IndexOf("Trade Price 16").
Beware though, if the column order changes for some reason, your code could break. The safe way would be to iterate through items via an indexer - row["Trade Price " + i].

Categories