Delete row in DGV if int is incremented? - c#

I have a method to save each row in a datagridview into the database, but I want to remove each row if it gets saved. I have this method:
public static void SaveMajEq(MajorEquipment_CreateView CView)
{
rowCount = 0;
// For each cell in the DataGrid, stores the information in a string.
for (rows = 0; rows < CView.dgvCreate.Rows.Count; rows++)
{
if (CView.dgvCreate.Rows[rows].Cells[col].Value != null)
{
// Creates a model, then populates each field from the cells in the table.
MeModel = new MajorEquipment_Model();
MeModel.EquipmentNumber = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[0].Value);
MeModel.EquipmentType = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[1].Value);
MeModel.Location = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[2].Value);
MeModel.Notes = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[3].Value);
Database_Facade.Operation_Switch(OPWRITE);
}
CView.dgvCreate.Rows.RemoveAt(rows);
}
MessageBox.Show(rowCount + " Entries stored in database.");
}
rowCount gets incremented in a try/catch method in a separate class, so if anything occurs, it wont be incremented. What I want to do is only implement this line:
CView.dgvCreate.Rows.RemoveAt(rows);
only if rowCount is incremented each time. I'm not sure how to implement this.

Revert the loop order
for (rows = CView.dgvCreate.Rows.Count - 1; rows >= 0 ; rows--)
Looping backward allow to remove the row processed by the loop without affecting the index of the next row to process.

Related

Change values of Cells in a Filtered DataGridView

I have DataGridView with a Column named flag and others.
When I apply a filter:
dataGridView2.DataSource =
new DataView(ds, "flag = 1", "tw_Name DESC", DataViewRowState.CurrentRows);
it shows only Rows where he Column flag value is equal to 1, but...
when I try to programmatically change this value, for example in 6 checked rows:
foreach (DataGridViewRow row in dataGridView2.Rows)
{
if (Convert.ToBoolean(row.Cells["zazn"].Value))
{
row.Cells["flags"].Value = 0;
}
}
three Rows disappear, one Row changes its value, two Rows do not change.
Next, when I click any Row, I get only 2 of the desired changes.
Since you're working with a DataTable, it's preferable that you modify the values of its Rows' content instead the DataGridView Cells while a Filter is active on the DataTable's DataView.
This causes the immediate propagation of the data changes, which your DataGridView will acknowledge. Not guaranteed if you do the opposite, trying to propagate the Control's changes to the DataSource.
This may go against the internal mechanics used by the Control to notify the changes to its DataSource: a DataGridView notify value changes of its Cells after the Cell edit has completed and validation has been performed.
You could try to call [DataGridView].EndEdit() and Validate(), it doesn't mean that in any circumstance the Control and the DataSource will synchronize when you expect it to happen.
Set the Filter and order the View:
Note that the order is applied to the DefaultView, not the DataTable. The Rows' order in the DataTable remains unchanged.
In your sample code, a filter is set to flag = 1, while you use another name for the Column in row.Cells["flags"].
var dView = (dataGridView2.DataSource as DataTable).DefaultView;
dView.RowFilter = "flag = 1";
dView.Sort = "tw_Name DESC";
When you need to change values in some of the Rows, access the DataTable using the DataGridView.DataSource and cast it to DataTable (or BindingSouce or whatever other source of data you have used).
You can now loop the DataRows and set new values to some Columns base on a condition, as in this case:
var dt = dataGridView2.DataSource as DataTable;
for (int i = 0; i <= dt.Rows.Count - 1; i++) {
var row = dt.Rows[i];
if (row["zazn"] != DBNull.Value && (bool)row["zazn"]) {
row["flag"] = 0;
}
}
You could do the same thing using the DataGridView.Row.DataBoundItem, which is a DataRowView in this case, looping backwards (to only loop the visible Rows):
var dt = dataGridView2.DataSource as DataTable;
//BACKWARDS - also assuming there's a NewRow, so Rows.Count - 2
for (int i = dataGridView2.Rows.Count - 2; i >= 0; i--) {
var row = (dataGridView2.Rows[i].DataBoundItem as DataRowView).Row;
if (row["zazn"] != DBNull.Value && (bool)row["zazn"]) {
row["flag"] = 0;
}
}
If you do the same but with a forward loop:
for (int i = 0; i < dataGridView2.Rows.Count - 1; i++) { ... }
you're in the same situation as before.

'Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound.'

I want to get user's input on how many rows he/she wants and then add that number of rows to the datagridview, while the datagridview is being populated with it's data.
This way an ecxeption occurs,System.InvalidOperationException.
Is there a work around for this?
int numberOfRows = Int32.Parse(txt_numberofrows.Text.Trim());
for (var i = 1; i < numberOfRows; i++)
{
expenseList.Rows.Add(numberOfRows);
}

does OnAutoGeneratingColumn e.cancel affect Table.Column.Count?

If I use OnAutoGeneratingColumn to cancel some columns that I don't necessarily want to generate, will it affect the number of columns in Table.Columns.Count?
Context
I'm iterating through a table, row by row, taking each value and passing it through to an insert SQL command. Right now it lines up so that each entry is associated properly. Will I disrupt this with e.cancel? Will row[1] no longer point to what it once did if row[0] was e.cancel'd?
for (int i = 0; i < table.Dummy.Columns.Count; i++)
{
// if we're past our first entry, add room for the next before entering it
if (i != 0)
{
InsertIntoTableQuery.AddIntPrm();
}
//if our column has an entry, add it into our table.
if (row[i] != null)
{
InsertIntoTableQuery.Prms[i].Val = row[i];
}
}
No! I figured out why I was erroring and this wasn't the cause. you can cancel column generation in the wpf datagrid without actually altering the table index's. In hindsight that's pretty obvious.

How to get range of last column excel (spreadsheetgear)

I'm trying to get the total number of columns so that i can set my range from column C to N column. I'm trying to go through each column and pull out the data i need into an array until i reach the last column with data in it.
I tried the below which works for one row, but none of the others i have.
IRange strategyname = foratworkbook.Worksheets["Strategy"].Cells["C4"].CurrentRegion;
C D E
9.040% 10.910% 6.050%
4.920% 5.510% 3.430%
53.030% 64.400% 36.030%
Any Ideas?
Thanks
If you know the maximum size of the array you can pull the entire table A:N x row nums into C# as a DataTable, find the first null column and first null row and then remove the columns and rows that are null from that DataTable. That is a reasonably quick and straightforward procedure.
These functions should return the first null row and column in a datatable
public static int findNullRow(DataTable dt)
{
int row = 0;
for (int a = 0; a < dt.Rows.Count; a++)
{
if (dt.Rows[a][0] == null)
{
row = a;
break;
}
}
return row;
}
public static int findNullColumn(DataTable dt)
{
int col = 0;
for (int i = 0; i < dt.Columns.Count; i++)
{
if (dt.Rows[0][i] == null)
{
col = i;
break;
}
}
return col;
}
The alternative is work iteratively across the first row of the spreadsheet pulling out the individual cell values and testing to find the first null column. Do the same for the first column of data until you find the first null row.
My feeling is that the first method would be quicker unless the potential number of rows is very large.
Following links will Help You for reading the data up to last edited range.
SpreadSheetGear - read unique values from Excel column
and
Get the number of rows of data with SpreadSheetGear?

Remove TableCell from each TableRow c#

I have used C# Table to display HTML Table in aspx page. I want to remove column from that Table.
DataTable getTxnOutput = // Get DataTable by Calling Stored Procedure;
Table txnOutputs = Generix.convertDataTable2HTMLTable(getTxnOutput);
foreach (TableRow trOutput in txnOutputs.Rows)
{
if (trOutput.TableSection == TableRowSection.TableBody)
{
/* Here i am doing some operation using column which i want to delete afterwards */
txnOutputs.Rows[0].Cells.Remove(trOutput.Cells[6]); //Now delete that column
}
}
Page.Controls.Add(txnOutputs);
But above code will delete cell only in first row.
How can I delete in every row without using further more loops.
I found Solution but can i incorporate same in above loop... I just want to avoid two loops..
for (int k = 0; k < txnOutputs.Rows.Count; k++)
{
txnOutputs.Rows[k].Cells.Remove(txnOutputs.Rows[k].Cells[6]);
}
Shouldn't this line
txnOutputs.Rows[0].Cells.Remove(trOutput.Cells[6]);
be
trOutput.Cells.Remove(trOutput.Cells[6]);?
Try this:
DataTable getTxnOutput = // Get DataTable by Calling Stored Procedure;
Table txnOutputs = Generix.convertDataTable2HTMLTable(getTxnOutput);
int i = 0;
foreach (TableRow trOutput in txnOutputs.Rows)
{
if (trOutput.TableSection == TableRowSection.TableBody)
{
/* Here i am doing some operation using column which i want to delete afterwards */
txnOutputs.Rows[i].Cells.Remove(trOutput.Cells[6]); //Now delete that column
}
i++;
}
Page.Controls.Add(txnOutputs);
You will have to include the forloop inside if, and use a Variable something like viewstate[X]=1 inside if statement, and check
if(viewstate[X]==1)
{
// logic here
}
viewstate[X]=0;
run for loop
after end of For loop set viewstate[X]=0
so that you can run for loop only once else it will loop through every row.

Categories

Resources