I have a DataGridView on a WinForms that the user pastes the data or imports from an Excel file. I'm validating the cells through a button click, which calls the method below. I'm wondering if there is a "better" way of writing the if/else statements.
Note: I am aware of the DataGridView.CellValidating event but I would rather not use that, unless someone suggests a better work around using this event than the method I have written.
Here is my method being called from the button_Click
private async void ValidateGridCells()
{
string numberHeader = dgvAddNumbers.Columns[0].HeaderText;
string accountHeader = dgvAddNumbers.Columns[1].HeaderText;
string statusHeader = dgvAddNumbers.Columns[2].HeaderText;
string dateHeader = dgvAddNumbers.Columns[3].HeaderText;
string acLengthHeader = dgvAddNumbers.Columns[4].HeaderText;
if (dgvAddNumbers.Rows.Count > 1)
{
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
foreach (DataGridViewCell cell in row.Cells)
{
cell.ErrorText = "";
}
}
}
if (numberHeader.Equals("Number"))
{
//Number cannot exist in DB already from Numbers table
//Number can only appear once in datagridview
//Number must be 10 digits ONLY
var numbersList = new List<string>();
var aniListFromDb = new List<dynamic>(await DataAccess.FetchNumbersFromDatabase(ConfigReader.GetValue("ConnectionStrings", "DB"), ConfigReader.GetValue("StoredProcedures", "FetchAllNumbers")));
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
numbersList.Add(row.Cells[0].ToString());
}
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
if (row.IsNewRow) { continue; }
//Check for empty Number and length
if (string.IsNullOrEmpty(row.Cells[0].Value.ToString()) || row.Cells[0].Value.ToString().Length != 10)
{
row.Cells[0].ErrorText = "Number must be 10 digits";
continue;
}
//Check for multiples of the same Number
else if (numbersList.Where(a => a == row.Cells[0].Value.ToString()).Count() > 0)
{
row.Cells[0].ErrorText = "Number already exists in the grid";
continue;
}
//Check if Number is already in DB
else if (aniListFromDb.Where(a => a.ANI == row.Cells[0]).Count() > 0)
{
row.Cells[0].ErrorText = "Number already exists in the database";
continue;
}
//Check for valid NPA/NXX
else
{
var npa = row.Cells[0].Value.ToString()[..3];
var nxx = row.Cells[0].Value.ToString().Substring(3, 3);
//Validate NPA
if (_npaList.Where(x => x.NPA == npa).Count() == 0)
{
row.Cells[0].ErrorText = "NPA not valid";
}
//Validate NXX
if (_nxxList.Where(x => x.NXX == nxx).Count() == 0)
{
row.Cells[0].ErrorText = "NXX not valid";
}
}
}
}
if (accountHeader.Equals("Account Number"))
{
//Account Number must exist
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
if (row.IsNewRow) { continue; }
if (string.IsNullOrEmpty(row.Cells[1].Value.ToString()))
{
row.Cells[1].ErrorText = "Account Number is missing";
continue;
}
else if (MainForm.activeAccounts.Where(a => a.AccountNumber == row.Cells[1].Value.ToString()).Count() == 0)
{
row.Cells[1].ErrorText = "Account Number is not valid";
}
}
}
if (statusHeader.Equals("Status"))
{
//Status needs to be the same as in enums
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
if (row.IsNewRow) { continue; }
if (string.IsNullOrEmpty(row.Cells[2].Value.ToString()))
{
row.Cells[2].ErrorText = "Status is missing";
continue;
}
else if (!Enum.GetNames(typeof(FormConstants.StatusDropDownValues)).Any(e => row.Cells[2].Value.ToString().Contains(e)))
{
row.Cells[2].ErrorText = "Status is not valid";
}
}
}
if (dateHeader.Equals("Active Date"))
{
//Activate Date must be current or greater date
DateTime today = DateTime.Now;
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
DateTime dt = DateTime.Now.AddDays(-1);
if (row.IsNewRow) { continue; }
if (!string.IsNullOrEmpty(row.Cells[3].Value.ToString()))
{
dt = DateTime.Parse(row.Cells[3].Value.ToString());
}
if (string.IsNullOrEmpty(row.Cells[3].Value.ToString()))
{
row.Cells[3].ErrorText = "Activation Date is missing";
continue;
}
else if (dt < today)
{
row.Cells[3].ErrorText = "Date must be today or in the future";
}
}
}
if (acLengthHeader.Equals("AC Length"))
{
//Account code length needs to be >=0 and <=10
foreach (DataGridViewRow row in dgvAddNumbers.Rows)
{
if (row.IsNewRow) { continue; }
if (string.IsNullOrEmpty(row.Cells[4].Value.ToString()))
{
row.Cells[4].ErrorText = "Account length is missing";
continue;
}
else if ((int.Parse(row.Cells[4].Value.ToString()) < 0) || (int.Parse(row.Cells[4].Value.ToString()) > 10))
{
row.Cells[4].ErrorText = "Length can only be between 0-10";
}
}
}
}
This is how I am pasting the data to the DataGridView from the KeUp event on the grid:
private void PasteToDataGridView(bool clearRows)
{
var gridView = this.dgvAddNumbers;
DataObject o = (DataObject)Clipboard.GetDataObject();
if (o.GetDataPresent(DataFormats.Text))
{
if (clearRows)
{
if (gridView.RowCount > 0)
gridView.Rows.Clear();
}
string[] pastedRows = Regex.Split(o.GetData(DataFormats.Text).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n");
foreach (string pastedRow in pastedRows)
{
string[] pastedRowCells = pastedRow.Split(new char[] { '\t' });
int myRowIndex = gridView.Rows.Add();
using (DataGridViewRow myDataGridViewRow = gridView.Rows[myRowIndex])
{
for (int i = 0; i < pastedRowCells.Length; i++)
myDataGridViewRow.Cells[i].Value = pastedRowCells[i];
}
}
}
}
Related
I built a winform project. This project open a mhtml file, then, he display the datagrid and remove the empty column.
i used much time "invoke" in my code. I would like to know how can i put this data into a DataTable or List and then binded the grid to it.
Here is the code :
{
public partial class Form1 : Form
{
private readonly string ConvertedFileName = "page.html";
private readonly List<string> ColumnsToSeparate = new List<string>() { "life limit", "interval" }; // Delete these columns
private readonly List<string> ExtraColumnsToAdd = new List<string>() { "Calendar", "Flight Hours", "Landing" }; // Add these columns
public Form1()
{
InitializeComponent();
this.Text = $"MhtmlTablesHunter v{Application.ProductVersion}";
}
//browse for specific file type , in this case its .mhtml
private void btnBrowse_Click(object sender, EventArgs e)
{
using (OpenFileDialog openFileDialog = new OpenFileDialog())
{
openFileDialog.Title = "Please choose the MHTML file";
openFileDialog.Filter = "MHTML files (*.mhtml)|*.mhtml;"; //the file type specified here
openFileDialog.RestoreDirectory = false;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
textBoxSourceFile.Text = openFileDialog.FileName;
checkAndExtractTable();
}
}
}
private void checkAndExtractTable()
{
string sourcePath = textBoxSourceFile.Text;
if (!string.IsNullOrEmpty(sourcePath)) //check if the input file path is not empty
{
if (File.Exists(sourcePath)) //check if the input file path is exists
{
Task.Run(async () => await ExtractTable(sourcePath)); //run the extraction process in a thread for the UI to be more responsive
}
else
{
MessageBox.Show("Source file doesn't exist.");
}
}
else
{
MessageBox.Show("Please select the source file.");
}
}
//This part concern the headers, rows and columns
public async Task<string> ExtractTable(string sourcePath)
{
try
{
var doc = new HtmlAgilityPack.HtmlDocument();
var converter = new MimeConverter(); //converter used to convert mhtml file to html
if (File.Exists(ConvertedFileName)) //check if previously converted file is exist
{
File.Delete(ConvertedFileName); //delete the file
}
using (FileStream sourceStream = File.OpenRead(sourcePath))
{
using (FileStream destinationStream = File.Open("page.html", FileMode.Create))
{
await converter.Convert(sourceStream, destinationStream); //convert the file to html, it will be stored in the application folder
}
}
doc.Load(ConvertedFileName); //load the html
var tables = doc.DocumentNode.SelectNodes("//table"); //get all the tables
HtmlAgilityPack.HtmlNode table = null;
if (tables.Count > 0)
{
table = tables[tables.Count - 1]; //take the last table
}
if (table != null) //if the table exists
{
dataGridView1.Invoke((Action)delegate //we use delegate because we accessing the datagridview from a different thread
{
this.dataGridView1.Rows.Clear();
this.dataGridView1.Columns.Clear();
});
var rows = table.SelectNodes(".//tr"); //get all the rows
var nodes = rows[0].SelectNodes("th|td"); //get the header row values, first item will be the header row always
string LifeLimitColumnName = ColumnsToSeparate.Where(c => nodes.Any(n => n.InnerText.ToLower().Contains(c))).FirstOrDefault();
if (string.IsNullOrWhiteSpace(LifeLimitColumnName))
{
LifeLimitColumnName = "Someunknowncolumn";
}
List<string> headers = new List<string>();
for (int i = 0; i < nodes.Count; i++) // LOOP
{
headers.Add(nodes[i].InnerText);
if (!nodes[i].InnerText.ToLower().Contains(LifeLimitColumnName))
{
dataGridView1.Invoke((Action)delegate
{
dataGridView1.Columns.Add("", nodes[i].InnerText);
});
}
}
int indexOfLifeLimitColumn = headers.FindIndex(h => h.ToLower().Contains(LifeLimitColumnName));
if (indexOfLifeLimitColumn > -1)
{
foreach (var eh in ExtraColumnsToAdd)
{
dataGridView1.Invoke((Action)delegate
{
dataGridView1.Columns.Add("", eh); //add extra header to the datagridview
});
}
}
for (int i = 1; i < rows.Count; i++) ///loop through rest of the rows
{
var row = rows[i];
var nodes2 = row.SelectNodes("th|td"); //get all columns in the current row
List<string> values = new List<string>(); //list to store row values
for (int x = 0; x < nodes2.Count; x++)
{
//rowes.Cells[x].Value = nodes2[x].InnerText;
string cellText = nodes2[x].InnerText.Replace(" ", " ");
values.Add(cellText); //add the cell value in the list
}
// Factory for -> Calendar, Flight Hours, Landings
if (indexOfLifeLimitColumn > -1)
{
values.RemoveAt(indexOfLifeLimitColumn);
string lifeLimitValue = nodes2[indexOfLifeLimitColumn].InnerText.Replace(" ", " ");
string[] splittedValues = lifeLimitValue.Split(' ');
for (int y = 0; y < ExtraColumnsToAdd.Count; y++)
{
if (ExtraColumnsToAdd[y] == "Calendar")
{
string valueToAdd = string.Empty;
string[] times = new string[] { "Years", "Year", "Months", "Month", "Day", "Days" };
if (splittedValues.Any(s => times.Any(t => t == s)))
{
var timeFound = times.Where(t => splittedValues.Any(s => s == t)).FirstOrDefault();
int index = splittedValues.ToList().FindIndex(s => s.Equals(timeFound));
valueToAdd = $"{splittedValues[index - 1]} {timeFound}";
}
values.Add(valueToAdd);
}
else if (ExtraColumnsToAdd[y] == "Flight Hours")
{
string valueToAdd = string.Empty;
if (splittedValues.Any(s => s == "FH"))
{
int index = splittedValues.ToList().FindIndex(s => s.Equals("FH"));
valueToAdd = $"{splittedValues[index - 1]} FH";
}
values.Add(valueToAdd);
}
else
{
string valueToAdd = string.Empty;
if (splittedValues.Any(s => s == "LDG"))
{
int index = splittedValues.ToList().FindIndex(s => s.Equals("LDG"));
valueToAdd = $"{splittedValues[index - 1]} LDG";
}
values.Add(valueToAdd);
}
}
}
dataGridView1.Invoke((Action)delegate
{
this.dataGridView1.Rows.Add(values.ToArray()); //add the list as a row
});
}
//This code remove the empty row
dataGridView1.Invoke((Action)delegate
{
int[] rowDataCount = new int[dataGridView1.Columns.Count];
Array.Clear(rowDataCount, 0, rowDataCount.Length);
for (int row_i = 0; row_i < this.dataGridView1.RowCount; row_i++)
{
for (int col_i = 0; col_i < this.dataGridView1.ColumnCount; col_i++)
{
var cell = this.dataGridView1.Rows[row_i].Cells[col_i];
string cellText = cell.Value.ToString();
if (!String.IsNullOrWhiteSpace(cellText))
{
rowDataCount[col_i] += 1;
}
}
}
int removedCount = 0;
for (int index = 0; index < rowDataCount.Length; index++)
{
if (rowDataCount[index] == 0)
{
this.dataGridView1.Columns.RemoveAt(index - removedCount);
removedCount++;
}
}
});
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return string.Empty;
}
private void textBoxSourceFile_TextChanged(object sender, EventArgs e)
{
}
}
}
Somebody can help me please? thanks a lot !
I want to change the value of datagridview column according to the condition if the cell.value is minimum of the all values the cell must contain "L" , that is low. If the value is highest of all the cell.value = "H" rest should be medium. This is what i have done so far:
//Function to display interaction as High, Medium and Low
public void ShowInteraction(DataGridView dv, string columnName)
{
//MAX
var Max = dv.Rows.Cast<DataGridViewRow>()
.Max(r => Convert.ToDouble(r.Cells[columnName].Value));
//MIN
List<double> arr = new List<double>();
foreach (DataGridViewRow row in dv.Rows)
{
if (row != null && row.Cells[columnName].Value != null)
{
arr.Add(Convert.ToDouble(row.Cells[columnName].Value.ToString()));
}
}
double Min = arr.Min();
//show interaction in datagridview as H, M nad L
foreach (DataGridViewRow row in dv.Rows)
{
if (row.Cells[columnName].Value != null)
{
if ((double)row.Cells[columnName].Value == Min)
{
row.Cells[columnName].Value = Convert.ToString( "L" );
}
else if ((double)row.Cells[columnName].Value == Max)
{
row.Cells[columnName].Value = Convert.ToString( "H" );
}
else if ((double)row.Cells[columnName].Value < Max && (double)row.Cells[columnName].Value > Min)
{
row.Cells[columnName].Value = Convert.ToString("M");
}
else if ((double)row.Cells[columnName].Value == 0.0000)
{
row.Cells[columnName].Value = Convert.ToString("N");
}
else
{
row.Cells[columnName].Value = Convert.ToString("L");
}
}
}
}
And this the result:
My problem is that the medium and high values are showing but some times it escape the lowest value and do not show any "L" at some columns. The data generated is random data.
I cleaned up your code a little bit and I'm not seeing the error you are. Let me know if this helps you with your issue or not.
public partial class MainForm : Form {
public MainForm() {
InitializeComponent();
DataGridView dgv = new DataGridView();
dgv.Columns.Add("columnName", "columnName");
dgv.AllowUserToAddRows = false;
dgv.Rows.Add(21.0);
dgv.Rows.Add(15.0);
dgv.Rows.Add(20.0);
dgv.Rows.Add(25.0);
dgv.Rows.Add(30.12354122);
this.Controls.Add(dgv);
ShowInteraction(dgv, "columnName");
}
public void ShowInteraction(DataGridView dv, string columnName) {
List<double> values = dv.Rows.Cast<DataGridViewRow>().Select(row => Convert.ToDouble(row.Cells[columnName].Value)).ToList();
double Max = values.Max();
double Min = values.Min();
foreach (DataGridViewRow row in dv.Rows)
{
if (row.Cells[columnName].Value != null)
{
double cellValue = Convert.ToDouble(row.Cells[columnName].Value);
var cell = row.Cells[columnName];
if (cellValue == Min)
{
cell.Value = "L";
}
else if (cellValue == Max)
{
cell.Value = "H";
}
else if (cellValue < Max && cellValue > Min)
{
cell.Value = "M";
}
else if (cellValue == 0)
{
cell.Value = "N";
}
else
{
cell.Value = "L";
}
}
}
}
}
This is all of the code i have done so far. The system has a listview that has a column header:
subject name | 1st | 2nd | 3rd | 4th | Final Grades
If the column 1st to 4th contains value it will compute for the final grade of the student. sum(1st to 4th) / 4 *50 + 50. if one of the column does not have a value then the user will be prompted and no final grades will be computed.
I am confused on how do i get all the listview value from 1st to 4th then automatically computes the final grade.
PLease help
private void button1_Click(object sender, EventArgs e)
{
flag = false;
if (txt_numValue.Text != "")
{
char[] entereddata = txt_numValue.Text.ToCharArray();
foreach (char aChar in entereddata.AsEnumerable())
{
if (!Char.IsDigit(aChar))
{
MessageBox.Show("Please enter only numbers.", "In the field Numeric Value");
flag = true;
break;
}
}
}
else if (txt_numValue.Text == "")
{
MessageBox.Show("Please do not leave the field, 'Numeric Value', blank.", "Attention!");
flag = true;
}
if (flag == false)
{
string period = txt_gradingPeriod.Text;
string numeric = txt_numValue.Text;
int cell = 0;
if (period == "1st") { cell = 1; }
else if (period == "2nd") { cell = 2; }
else if (period == "3rd") { cell = 3; }
else if (period == "4th") { cell = 4; }
foreach (ColumnHeader header in listView1.Columns)
{
if (header.Text == period)
{
listView1.Items[0].SubItems[cell].Text = numeric;
break;
}
}
}
}
Once you have got all the data in your list view you can do something like this,
int sum = 0;
foreach (ListViewItem v in listView1.Items)
{
bool hasBlank = false;
for (int i = 0; i < v.SubItems.Count;i++ )
{
if (v.SubItems[i].Text == null || v.SubItems[i].Text == string.Empty)
{
//code
hasBlank = true;
break;
}
else
{
sum += Convert.ToInt16(v.SubItems[i].Text);
}
}
if (!hasBlank)
{
string grade="something";
//formula to calculate grade based on sum.set the result to string grade
v.SubItems[4].Text = grade;
}
else
{
v.SubItems[4].Text = "has blank";
}
sum = 0;
}
This will fill grade if all values are present else a message that it has a blank value.
I'm using Epplus to render an Excel spreadsheet into HTML. So far it's going very, very well, except for one thing... spanning merged cells. I just can't seem to get the logic right. I thought I would throw it out there to see how the community would deal with it. Here is my code so far.
public String ParseExcelStamps(String FileName)
{
FileInfo theFile = new FileInfo(FileName);
String html = "";
using (ExcelPackage xlPackage = new ExcelPackage(theFile))
{
var workbook = xlPackage.Workbook;
if (workbook != null)
{
for (int j = 1; j <= workbook.Worksheets.Count; j++)
{
Tab tab = new Tab();
html+= "<table style='border-collapse: collapse;font-family:arial;'><tbody>";
var worksheet = workbook.Worksheets[j];
tab.Title = worksheet.Name;
if (worksheet.Dimension == null) { continue; }
int rowCount = 0;
int maxColumnNumber = worksheet.Dimension.End.Column;
var convertedRecords = new List<List<string>>(worksheet.Dimension.End.Row);
var excelRows = worksheet.Cells.GroupBy(c => c.Start.Row).ToList();
excelRows.ForEach(r =>
{
rowCount++;
html += String.Format("<tr>");
var currentRecord = new List<string>(maxColumnNumber);
var cells = r.OrderBy(cell => cell.Start.Column).ToList();
Double rowHeight = worksheet.Row(rowCount).Height;
for (int i = 1; i <= maxColumnNumber; i++)
{
var currentCell = cells.Where(c => c.Start.Column == i).FirstOrDefault();
//look aheads for colspan and rowspan
ExcelRangeBase previousCellAbove = null;
ExcelRangeBase previousCell = null;
ExcelRangeBase nextCell = null;
ExcelRangeBase nextCellBelow = null;
try { previousCellAbove = worksheet.Cells[rowCount-1, i]; }catch (Exception) { }
try { previousCell = worksheet.Cells[rowCount, (i - 1)]; }catch (Exception) { }
try { nextCell = worksheet.Cells[rowCount, (i + 1)]; }catch (Exception) { }
try { nextCellBelow = worksheet.Cells[rowCount+1, i]; }catch (Exception) { }
if ((previousCell != null) && (previousCell.Merge) && (currentCell != null) && (currentCell.Merge)){continue;}
if ((previousCellAbove != null) && (previousCellAbove.Merge) && (currentCell != null)) {continue; }
if (currentCell == null)
{
html += String.Format("<td>{0}</td>", String.Empty);
}
else
{
int colSpan = 1;
int rowSpan = 1;
if ((nextCell != null) && (nextCell.Merge) && (currentCell.Merge)) {
colSpan = 2;
// Console.WriteLine(String.Format("{0} - {1}", currentCell.Address, nextCell.Address));
}
if ((nextCellBelow != null) && (nextCellBelow.Merge) && (currentCell.Merge)) {
Console.WriteLine(String.Format("{0} - {1}", currentCell.Address, nextCellBelow.Address));
}
html += String.Format("<td colspan={0} rowspan={1}>{2}</td>", colSpan, rowSpan, currentCell.Value);
}
}
html += String.Format("</tr>");
});
html += "</tbody></table>";
}//worksheet loop
}
}
return html;
}
As far as I can tell this is exactly what you need. What you were missing was the MergedCells property on the worksheet which lists all merged cells in the sheet.
My code handles row spans, column spans, and both at the same time. I did some testing with a spreadsheet that included both row, column and row/column spanning. In all cases they worked perfectly.
Code
int colSpan = 1;
int rowSpan = 1;
//check if this is the start of a merged cell
ExcelAddress cellAddress = new ExcelAddress(currentCell.Address);
var mCellsResult = (from c in worksheet.MergedCells
let addr = new ExcelAddress(c)
where cellAddress.Start.Row >= addr.Start.Row &&
cellAddress.End.Row <= addr.End.Row &&
cellAddress.Start.Column >= addr.Start.Column &&
cellAddress.End.Column <= addr.End.Column
select addr);
if (mCellsResult.Count() >0)
{
var mCells = mCellsResult.First();
//if the cell and the merged cell do not share a common start address then skip this cell as it's already been covered by a previous item
if (mCells.Start.Address != cellAddress.Start.Address)
continue;
if(mCells.Start.Column != mCells.End.Column) {
colSpan += mCells.End.Column - mCells.Start.Column;
}
if (mCells.Start.Row != mCells.End.Row)
{
rowSpan += mCells.End.Row - mCells.Start.Row;
}
}
//load up data
html += String.Format("<td colspan={0} rowspan={1}>{2}</td>", colSpan, rowSpan, currentCell.Value);
int rowsCount = 0;
//This checks to see that both textbox for items and subitems do not gain focus at the same time
if (textBoxSubItems.Text != string.Empty)
txtItems.Enabled = false;
else
txtItems.Enabled = true;
if (comboBoxItems.SelectedItem != null)
{
int idx = dataGridViewTimesheet.Rows.Add();
DataGridViewRow row = dataGridViewTimesheet.Rows[idx];
row.Cells["items"].Value = comboBoxItems.SelectedItem.ToString() + "-" + textBoxSubItems.Text;
row.Cells["fromTime"].Value = DateTime.Now.ToLongTimeString();
row.Cells["toTime"].Value = null;
row.Cells["duration"].Value = null;
row.Cells["subTotal"].Value = null;
// row.Cells["comments"].Value = "1";
}
else
MessageBox.Show("Please select an item");
string strGetColumnValue;
if (dataGridViewTimesheet.Rows.Count != 0)
rowsCount = dataGridViewTimesheet.Rows.Count;
else
MessageBox.Show("No row in the datagridview");
while (dataGridViewTimesheet.Rows.Count > 0)
{
try
{
if (dataGridViewTimesheet.CurrentRow != null)
for (int counter = 0; counter < dataGridViewTimesheet.Columns.Count; counter++)
{
if (dataGridViewTimesheet.Columns[counter].Index == 3)
{
strGetColumnValue = dataGridViewTimesheet.Rows[rowsCount].Cells[counter].Value.ToString();
dataGridViewTimesheet.Rows[rowsCount - 1].Cells[3].Value = strGetColumnValue;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
Please i have 6 columns in a datagridview, the rows are added dynamically. What i want is when rows are more than one in the datagridview it should assign the value of the second column on the current(the last row created) row to the third column of the previous row. How do I achieve this.
Try this kind of thing
int count =1;
foreach (DataGridRow row in dataGridViewTimesheet.Rows)
{
if (count % 2 == 0)
{
string secondColumn = dataGridViewTimesheet.Rows[count -1].Cells[1].ToString();
dataGridViewTimesheet.Rows[count].Cells[2].Value = secondColumn;
}
count++;
}