Add row to specific column by header name/text - c#

I have a column named "HeaderText_Name" and in this column, I want to add a row that has the text "Row" under that column.
I attempted to write some pseudo-code for it
databaseGridView.Rows["HeaderText_Name"].Add("Row");
If I do
databaseGridView.Rows.Add("Row");
It adds it to the first column no matter what. I also can't do something like
databaseGridView.Rows.Add("","","Row");
Then it adds blanks to the first two columns and I also don't know how which index the column is. So I would be more helpful if it was by Name or text.
Here is the actual code I have so far..
for (int i = 0; i < completeInfoMatches.Count; i++) {
databaseGridView.Rows.Add();
databaseGridView.Rows[0].Cells[e.Node.Text].Value = completeInfoMatches[i].Groups[1].ToString();
}
Now, completeInfoMatches has more than 1 match because it's regex. How can I change the 0 to make it work?
UPDATE
int currentRowIndex = 0;
databaseGridView.Columns.Add(e.Node.Text.Replace(" ", string.Empty), e.Node.Text);
for (int i = 0; i < completeInfoMatches.Count; i++) {
databaseGridView.Rows.Add();
databaseGridView.Rows[currentRowIndex].Cells[e.Node.Text.Replace(" ", string.Empty)].Value = completeInfoMatches[i].Groups[1].ToString();
currentRowIndex = currentRowIndex + 1;
}
I'm getting a lot of extra blank rows because of Row.Add

Try something like this:
foreach(int i = 0; i < completeInfoMatches.Count; i++){
var index = databaseGridView.Rows.Add();
databaseGridView.Rows[index].Cells[e.Node.Text].Value = completeInfoMatches[i].Groups[1].ToString();
}

With the help of #Forlani ...
int currentRowIndex = 0;
int actualRowIndex = databaseGridView.Rows.Count;
for (int i = 0; i < completeInfoMatches.Count; i++) {
var index = 0;
if (actualRowIndex < completeInfoMatches.Count) {
index = databaseGridView.Rows.Add();
}
databaseGridView.Rows[currentRowIndex].Cells[e.Node.Text.Replace(" ", string.Empty)].Value = completeInfoMatches[i].Groups[1].ToString();
currentRowIndex = currentRowIndex + 1;
}

Related

Exporting DataGridView records to Excel

I have a datagridview with several columns and different report types, where I have a method to export the records to Excel spreadsheet, in this datagridview I leave some columns like: visible = false according to the selected report type.
In the export method for spreadsheet I have a validation to consider only visible cells, true but it is not working.
int XLRow = 1;
int XLCol = 1;
// Export header
for (int i = 0; i < datagrid.Columns.Count; i++)
{
if (datagrid.Columns[i].Visible == true)
xlWorkSheet.Cells[XLRow, XLCol++] = datagrid.Columns[i].HeaderText;
}
XLRow = 2;
XLCol = 1;
// Controls for scrolling through records do DataGridView
for (int i = 0; i < datagrid.RowCount; i++)
{
for (int j = 0; j < datagrid.ColumnCount; j++)
{
DataGridViewCell cell = datagrid[j, i];
string conteudo = string.Empty;
if ((cell.Value != null) && (!string.IsNullOrEmpty(cell.Value.ToString())) && cell.Visible == true)
{
conteudo = cell.Value.ToString();
if ((Funcoes.EhNumerico(conteudo)) && (conteudo.Length > 8))
{
conteudo = string.Concat("'", conteudo);
}
xlWorkSheet.Cells[XLRow, XLCol++] = conteudo;
}
XLRow++;
XLCol = 1;
}
}
The spreadsheet leaves with the columns that are visible = false in white, as follows:
How can I resolve this?
In other words… in the first for loop… if the column is not visible… then you DO NOT want to increment i… and this is obviously going to mess up the for loop. Hence my suggestion to create two (2) int variables… int XLRow and int XLColumn, then use those indexes specifically for the WORKSHEET. Then loop through the grid columns as your code does using i and j, however, when a column is found that is not visible, then you DO NOT want to increment the XLCol index.
It will be a challenging juggling the loops i or j variables to also be used as an index into the worksheet columns as they may be completely “different” indexes. This is why I say “separate” them from the git go and keep it simple. Something like…
EDIT per OP comment…
I had the code that “increments” the XLCol “INSIDE” the if statement that checks for a null cell value or an empty string cell value… meaning if the cell is null or empty… then XLCol does not get incremented. The line xlWorkSheet.Cells[XLRow, XLCol++] = conteudo; should be “outside” that if statement. I have edited the code and it should work properly now with “empty” cells.
int XLRow = 1;
int XLCol = 1;
for (int i = 0; i < datagrid.Columns.Count; i++) {
if (datagrid.Columns[i].Visible == true)
xlWorkSheet.Cells[XLRow, XLCol++] = datagrid.Columns[i].HeaderText;
}
XLRow = 2;
XLCol = 1;
for (int i = 0; i < datagrid.RowCount; i++) {
for (int j = 0; j < datagrid.ColumnCount; j++) {
if (datagrid.Columns[j].Visible) {
DataGridViewCell cell = datagrid[j, i];
string conteudo = string.Empty;
if ((cell.Value != null) && (!string.IsNullOrEmpty(cell.Value.ToString()))) {
conteudo = cell.Value.ToString();
if ((Funcoes.EhNumerico(conteudo)) && (conteudo.Length > 8)) {
conteudo = string.Concat("'", conteudo);
}
//xlWorkSheet.Cells[XLRow, XLCol++] = conteudo; <- XLCol incremented ONLY if cell is not null or empty and this is wrong
}
xlWorkSheet.Cells[XLRow, XLCol++] = conteudo;
}
}
XLRow++;
XLCol = 1;
}

How to reverse rows in a DataGridView

I am using a data grid, but the values do not display as I would like them to. My current code is below, how would I go about inverting the rows?
string[] strOutput = strLine.Split('_', ',','=');
int totalRows = Convert.ToInt16(strOutput[4]);
int totalCols = Convert.ToInt16(strOutput[5]);
int itemIndex = 8;
for (int i = 0; i < totalCols; i++){
dataGridView1.Columns.Add("Col", "Col");
}
dataGridView1.Rows.Add(totalRows);
for (int i = 0; i < totalRows; i++) {
for (int j = 0; j < totalCols; j++) {
dataGridView1.Rows[i].Cells[j].Value = strOutput[itemIndex];
itemIndex += 2;
}
}
dataGridView1.Visible = true;
To invert i.e. reverse DataGridViewRows you can use this:
void ReverseDGVRows(DataGridView dgv)
{
List<DataGridViewRow> rows = new List<DataGridViewRow>();
rows.AddRange(dgv.Rows.Cast<DataGridViewRow>());
rows.Reverse();
dgv.Rows.Clear();
dgv.Rows.AddRange(rows.ToArray());
}
If you only need to do it once you could instead either:
loop over the lines of the source file in reverse
or instead of Adding the rows (to the end) Insert at the top:
dtnew.Rows.Insert(0, currentDataRowView.Row);
Inverting rows:
"DataGridView.Rows".- will give you "DataGridViewRowCollection"
Iterate the collection in reverse order and create a new datatable. (for loop from max size to zero)
Assign the new datatable to datagridview source.
This rough code written in note pad for your idea. I do not have IDE now.
DataGridViewRowCollection dgRowColllection = dataGridView1.Rows;
DataTable dtnew = new DataTable();
for(i = dataGridView1.RowCount; i < 1 ; i--)
{
DataRowView currentDataRowView = dgRowColllection[i].Row;
dtnew.Rows.Add(currentDataRowView.Row);
}
dataGridView1.source = dtnew;
Can't comment on Pavan's answer because I don't have 50 reputation, but are you getting the error because the loop should be something like:
int totalRows = Convert.ToInt16(strOutput[4]);
int totalCols = Convert.ToInt16(strOutput[5]);
int itemIndex = 8;
for (int i = 0; i < totalCols; i++)
{
dataGridView1.Columns.Add("Col", "Col");
}
dataGridView1.Rows.Add(totalRows);
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalCols; j++)
{
dataGridView1.Rows[i].Cells[j].Value = strOutput[itemIndex];
itemIndex += 2;
}
DataGridViewRowCollection dgRowColllection = dataGridView1.Rows;
DataTable dtnew = new DataTable();
for (i = dataGridView1.Items.Count; i < 1; i--)
{
DataRowView currentDataRowView = dgRowColllection[i].Row;
dtnew.Rows.Add(currentDataRowView.Row);
}
dataGridView1.DataSource = dtnew;
}
dataGridView1.Visible = true;
}

Getting System.ArgumentOutOfRangeException while copy between two Datagridviews

If somebody could please help solve the following issue:
System.ArgumentOutOfRangeException : Index was out of range. Must be
non-negative and less than the size of the collection. Paarameter name
: index
The code:
for (int i = 0; i <= dataGridView2.Rows.Count ; i++)
{
for (int j = 0; j <= dataGridView3.Rows.Count; j++)
{
if (!string.IsNullOrEmpty(dataGridView2.Rows[i].Cells["supplier_name"].Value as string) && !string.IsNullOrEmpty(dataGridView3.Rows[j].Cells["brands_supplier"].Value as string))
{
if (dataGridView2.Rows[i].Cells["supplier_name"].Value.ToString() == dataGridView3.Rows[j].Cells["brands_supplier"].Value.ToString())
{
dataGridView2.Rows[i].Cells["brands_name"].Value += dataGridView3.Rows[j].Cells["brands_nume"].Value + " ";
}
}
else
{
break;
}
}
}
You try to access an element of your datagrid which doesn't exist.
You have to set your for condition to
for (int i = 0; i < dataGridView2.Rows.Count ; i++)
and
for (int j = 0; j < dataGridView3.Rows.Count; j++)
don't use <= because the index of dataGridView.Rows[] is 0 based.
For example, if your datagrid contains 3 elements you can reach them with:
var row1 = dataGrid.Rows[0]
var row2 = dataGrid.Rows[1]
var row3 = dataGrid.Rows[2]
And you try to access
var row4 = dataGrid.Rows[3] // Error because this item doesn't exist (System.ArgumentOutOfRangeException)
also, but this item doesn't exist
I think problem in cycle
for (int i = 0; i <= dataGridView2.Rows.Count ; i++)
You run one more time
use
for (int i = 0; i < dataGridView2.Rows.Count ; i++)

Getting only the last row in Datagrid with datagrid.items[index]

I am trying to run a loop on a datagrid having five rows, but I am only getting the last row in the datagrid.
for (int i = 0; i < mydataGrid.Items.Count; i++)
{
var newrow = (My_DTO)mydataGrid.Items[i];
MessageBox.Show(newrow.FirstName.ToString());
}
Try using this. This should help you get the row :
for (int i = 0; i < dataGrid.Items.Count; i++)
{
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromIndex(i);
}
Each time you call MessageBox.Show(newrow.Firstname.ToString()); you'll be overwriting the previous name.
Try:
String names = "";
for (int i = 0; i < mydataGrid.Items.Count; i++)
{
var newrow = (My_DTO)mydataGrid.Items[i];
names += newrow.FirstName.ToString());
}
MessageBox.Show(names);
That should just show the names one after the other with no spaces, but I'm not sure how you want to display the names, so that part is up to you.

Set dropdown list to initial value

I have manually added values in dropdown list using for loop.
for (int i = 1; i <= 31; i++)
{
date0.Items.Add(i.ToString());
date1.Items.Add(i.ToString());
date2.Items.Add(i.ToString());
date3.Items.Add(i.ToString());
}
for (int j = 1; j <= 12; j++)
{
month0.Items.Add(j.ToString());
month1.Items.Add(j.ToString());
month2.Items.Add(j.ToString());
month3.Items.Add(j.ToString());
}
for (int k = DateTime.Now.Year; k <= 2020; k++)
{
yyyy0.Items.Add(k.ToString());
yyyy1.Items.Add(k.ToString());
yyyy2.Items.Add(k.ToString());
yyyy3.Items.Add(k.ToString());
}
Now on clear button I want to clear out these values and set them to initial. I tried calling the function in which I have initialized them. But it's not happening. Can someone tell me why?
You will need to fill the dropdownlist only if the page is Not postback
if (! IsPostBack) {
//Fill out the dropdown list
}
and make sure to set SelectedIndex = 0 for those you want to set back to initial values
month0.SelectedIndex = 0;
You can reset it to the first record by setting the SelectedIndex to 0 so that the first element in the list will be selected:
date0.SelectedIndex = 0;
date1.SelectedIndex = 0;
date2.SelectedIndex = 0;
date3.SelectedIndex = 0;
month0.SelectedIndex = 0;
month1.SelectedIndex = 0;
month2.SelectedIndex = 0;
month3.SelectedIndex = 0;
yyyy0.SelectedIndex = 0;
yyyy1.SelectedIndex = 0;
yyyy2.SelectedIndex = 0;
yyyy3.SelectedIndex = 0;
You can put this on the Clear button.

Categories