How to read from a GridView - c#

Solution, for at least a specific cell: GridView1.Rows[i].Cells[j].Text;
I've build a simple CSV-Fileupload. After the user uploaded the file he should be able to evaluate the data. When the fileupload was successful the data gets loaded into the GridView1, with this code: (Problem below the code)
string[] readCSV = File.ReadAllLines(lblFilePath.Text);
DataTable dt = new DataTable();
bool bSplitMe = false;
foreach (var rLine in readCSV)
{
if (bSplitMe)
{
string[] aSplittedLine = rLine.Split(";".ToCharArray());
try
{
dt.Rows.Add(aSplittedLine);
}
catch(System.Exception)
{
txtBoxFileOut.Text = rLine;
break;
}
}
else
{
if (rLine.ToLower().StartsWith("definedtestid;"))
{
bSplitMe = true;
string[] aSplittedLine = rLine.Split(";".ToCharArray());
foreach (var rCol in aSplittedLine)
{
dt.Columns.Add(rCol);
}
}
else
{
txtBoxFileOut.Text += rLine.ToString() + "\n";
}
}
}
dt.Columns.Remove("Column1");
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
if (string.IsNullOrEmpty(dt.Rows[i][j].ToString()))
{
dt.Rows[i][j] = "0";
}
}
}
GridView1.DataSource = dt;
GridView1.DataBind();
After this the user should be able to select a row and display the data from that row in a chart.
Problem: I'm not able to read data from the cells I want, or to read from a "hardcoded" cell.
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e) {
GridViewRow row = GridView1.SelectedRow;
txtOutputfield.Text = row.Cells[2].Text;
}

Please check your cell index. Is it correct? For example: the third column will have index "2" not "3"
And, if you use a control to store the data, you need to find that control:
txtOutputfield.Text =
row.Cells[2].FindControl('placeyourcontrolnamehere').Text;

For a specific Cell this worked fine
txtOutputfield.Text = GridView1.Rows[i].Cells[j].Text;

Related

DataGridView won't show correctly after loading some data

I load data from SQLite to DataGridView. DataGridView doesn't show correctly. I have tried to use follow methods: Refresh, Paint, Update, Invalidate DataGridView.
If I minimize and maximize my program, then DataGridView shows correctly.
I execute it in the MainForm.
private void thicknessComboBox_TextChanged(object sender, EventArgs e)
{
List<string> tm1Deflection = database.ExecuteSelectQuery(connectionString, tm1ListCommand, parameters);
List<string> tension = database.ExecuteSelectQuery(connectionString, tensionListCommand, parameters);
var rowHeaders = new string[] { "TM-1 READING", "SPOKE TENSION (KGF)" };
var rows = new List<string[]> { tm1Deflection.ToArray(), tension.ToArray() };
formControl.SetDataGridViewValues(conversionTableGridView, tm1Deflection.Count, rowHeaders, rows); // This string filling DataGridView
}
Filling DataGridView locates in another class:
public void SetDataGridViewValues(DataGridView dataGridView, int columnCount, string[] rowHeaders, List<string[]> rows)
{
dataGridView.ColumnCount = columnCount;
dataGridView.RowHeadersWidth = 165;
int columnsWidth = (dataGridView.Width - dataGridView.RowHeadersWidth) / dataGridView.ColumnCount;
for (var i = 0; i < columnCount; i++)
{
dataGridView.Columns[i].Name = "";
dataGridView.Columns[i].Width = columnsWidth;
}
dataGridView.Rows.Clear();
if (rows.Count != rowHeaders.Length)
{
MessageBox.Show("Number of row headers must be equal number of rows!", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
else
{
for (var i = 0; i < rows.Count; i++)
{
dataGridView.Rows.Add(rows[i]);
dataGridView.Rows[i].HeaderCell.Value = rowHeaders[i];
}
}
}
Example with DataTable:
DataTable table = new DataTable();
table.Columns.Add("Column1", typeof(int));
table.Rows.Add(1);
conversionTableGridView.DataSource = table;
Error:
I have clicked on first cell:

Read Checkboxvalues that were dynamically created in a Datatable c#

I have this code that dynamically created my checkboxes. I have several columns of checkboxes and several rows, so it needs to be totally dynamical.
I don't know how i can read the values of the checkboxes and would like to ask for some help. BTW I would like to save the values in a multidimensional array.
Meldungtable.Columns.Add("Warnungen", typeof(string));
for (int meldungcnt = 0; meldungcnt < SPSWarnungsBausteinArray.Length; meldungcnt++)
{
Meldungtable.Rows.Add(SPSWarnungsBausteinArray[meldungcnt]);
}
WarnungenDataGridView.DataSource = Meldungtable;
for (int kameracnt = 1; kameracnt <= Kameraanzahl; kameracnt++)
{
DataGridViewCheckBoxColumn Kamerachk = new DataGridViewCheckBoxColumn();
Kamerachk.HeaderText = "Kamera" + kameracnt;
Kamerachk.Name = "KameraChkBox" + kameracnt;
Kamerachk.Width = 70;
WarnungenDataGridView.Columns.Add(Kamerachk);
}
I would read row by row and check for the checkbox name, that i have assigned before, but as I am reading the data in a different method I don't think this works out.
Please help
Display:
foreach (DataGridViewRow row in WarnungenDataGridView.Rows)
{
for (int col = 1; col < WarnungenDataGridView.ColumnCount; col++)
{
//DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell)row.Cells[col];
WarnungenDataGridView.Rows[row.Index].Cells[col].Value = "true";
}
}
foreach (DataGridViewRow row in WarnungenDataGridView.Rows)
{
DataGridViewCheckBoxCell CheckedCell = row.Cells[0] as DataGridViewCheckBoxCell;
if (CheckedCell.Value != null)
{
if (CheckedCell.Value == CheckedCell.TrueValue)
{
//It's checked! do something within your code where necessary
}
}
}

Set ComboBox in Specific Cell in DataGridView

I've seen multiple threads about combobox's in DataGridView rows/columns but nothing really focused on just one cell. I'm trying to loop through all the cells in the DataGridView and when it recognizes a Parameter that is supposed to have the options On/Off, it loads a ComboBox in.
The code I've been working on is:
dataGridView1.DataSource = typeof(Parameter);
dataGridView1.DataSource = _paramList;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
foreach (DataGridViewCell ce in row.Cells)
{
foreach (Information i in _information)
{
if (ce.Value.ToString() == "Light")
{
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.Items.Add("On");
c.Items.Add("Off");
dataGridView1.Rows[ce.RowIndex].Cells[ce.ColumnIndex] = c;
}
}
}
}
It throws an error "Collection was modified; enumeration operation may not execute." which I'm guessing has to do with it populating the cell with a combobox and trying to continue the foreach statement? Any ideas/change to fix this?
Thanks!
Foreach loops handle enumerators for you, they get this error (enumeration cannot continue, collection modified) quite easily. You can get around this by using for loops. I tested the below (tried with foreach first - no dice), and we seem to be good.
Also of note - I had to set the actual cell value to null before setting the new item. Without this, I got an error "value of datagridcomboboxcell is not valid" (or something similar).
Edit: I left out your third nested loop. It's not necessary for this proof of concept. This simply adds the combobox to 100% of cells.
Including all of my testing code for reproduction:
using System;
using System.Data;
using System.Windows.Forms;
namespace WindowsFormsApp5
{
public partial class Form1 : Form
{
private DataGridView oDg;
public Form1()
{
InitializeComponent();
CreateGrid();
this.Shown += Form1_Shown;
}
private void Form1_Shown(object sender, EventArgs e)
{
TestIt();
}
private void TestIt()
{
//works
for (int i = 0;i < oDg.RowCount; i++)
{
for (int j = 0;j< oDg.ColumnCount; j++)
{
oDg.Rows[i].Cells[j].Value = null; //this is important.
DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
c.Items.Add("On");
c.Items.Add("Off");
oDg.Rows[i].Cells[j] = c;
}
}
//does not work
//foreach (DataGridViewRow row in oDg.Rows)
//{
// foreach (DataGridViewCell ce in row.Cells)
// {
// oDg.Rows[ce.RowIndex].Cells[ce.ColumnIndex].Value = null;
// DataGridViewComboBoxCell c = new DataGridViewComboBoxCell();
// c.Items.Add("On");
// c.Items.Add("Off");
// oDg.Rows[ce.RowIndex].Cells[ce.ColumnIndex] = c;
// }
//}
}
private void CreateGrid()
{
oDg = new DataGridView();
oDg.Width = 800;
oDg.Height = 800;
oDg.DataSource = CreateDataSource();
this.Controls.Add(oDg);
}
private DataTable CreateDataSource()
{
DataTable oDt = new DataTable();
for(int i = 0; i < 8; i++)
{
DataColumn col = new DataColumn(i.ToString(),typeof (String));
oDt.Columns.Add(col);
}
for (int i = 0; i < 99; i++)
{
DataRow rw = oDt.NewRow();
for (int j = 0;j < oDt.Columns.Count; j++)
{
rw[j] = j.ToString();
}
oDt.Rows.Add(rw);
}
return oDt;
}
}
}

hide empty row in gridview

I want to hide empty row in one particular column. I tried to but negative. Below is my code:
protected void gvDb_DataBound(object sender, EventArgs e)
{
foreach (GridViewRow rw in gvDb.Rows)
{
if ((string.IsNullOrEmpty(rw.Cells[1].Text) | (rw.Cells[1].Text == "")))
{
rw.Visible = false;
}
}
}
for (int i = 0; i < gvDb.RowCount - 1; i++)
{
var row = gvDb.Rows[i];
if (string.IsNullOrEmpty(Convert.ToString(row.Cells[1].Value)))
{
row.Visible = false;
}
}
This will work,
use for instead of foreach to iterate all the rows except last row which is empty.

Tag Array c# winforms

The code below lets me show emails received in a listview on when the selected index is changed displays the body of the selected email in a RTB. The problem is i changed the code to work with a data grid view and now the Tag part wont work
void SomeFunc() // This line added by Jon
{
int i;
for (i = 0; i < bundle.MessageCount; i++)
{
email = bundle.GetEmail(i);
ListViewItem itmp = new ListViewItem(email.From);
ListViewItem.ListViewSubItem itms1 =
new ListViewItem.ListViewSubItem(itmp, email.Subject);
ListViewItem.ListViewSubItem itms2 =
new ListViewItem.ListViewSubItem(itmp, email.FromName);
itmp.SubItems.Add(itms1);
itmp.SubItems.Add(itms2);
listView1.Items.Add(itmp).Tag = i;
richTextBox1.Text = email.Body;
}
// Save the email to an XML file
bundle.SaveXml("email.xml");
}
private void listView1_SelectionChanged(object sender, EventArgs e)
{
if (listView1.SelectedCells.Count > 0)
{
// bundle is now accessible in your event handler:
richTextBox1.Text = bundle.GetEmail((int)listView1.SelectedCells[0].Tag).Body;
}
}
Code for data grid view
int i;
for (i = 0; i < bundle.MessageCount; i++)
{
email = bundle.GetEmail(i);
string[] row = new string[] { email.From, email.Subject, email.FromName };
object[] rows = new object[] { row };
foreach (string[] rowArray in rows)
{
dataGridView1.Rows.Add(rowArray);
}
} // This line added by Jon
i have created earlier the code for datagrid view but you already done it so i haven't posted in your last question but i think , you should give a try to the below code.
// i am creating a new object here but , you can have a single object on the form
DataGridView dgv = new DataGridView();
private DataTable EmailSource { get; set; }
dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgv.SelectionChanged+=new EventHandler(dgv_SelectionChanged);
Chilkat.MessageSet msgSet = imap.Search("ALL", true);
if (msgSet != null)
{
bundle = imap.FetchBundle(msgSet);
CreateDataTable();
if (bundle != null && dt!=null)
{
Chilkat.Email email;
int i;
for (i = 0; i < bundle.MessageCount; i++)
{
email = bundle.GetEmail(i);
if(email!=null)
{
DataRow drow = EmailSource.NewRow();
drow["Id"] = i.ToString();
drow["From"] = email.FromName;
drow["Subject"] = email.Subject;
drow["DateRecived"] = email.DateRecived;
// i am adding email body also
drow["Body"] =email.Body;
EmailSource.Rows.Add(drow);
}
}
// Save the email to an XML file
bundle.SaveXml("email.xml");
dgv.DataSource= EmailSource;
// Hiding Body from the grid
dgv.Columns["Body"].Visible =false;
}
}
// this event handler will show the last selected email.
void dgv_SelectionChanged(object sender, EventArgs e)
{
DataGridViewSelectedRowCollection rows = dgv.SelectedRows;
if (rows != null)
{
// get the last selected row
DataRow drow = rows[rows.Count - 1].DataBoundItem as DataRow;
if (drow != null)
{
richTextBox1.Text = drow["Body"];
}
}
}
private void CreateDataTable()
{
EmailSource = new DataTable();
EmailSource.Columns.Add("Id");
EmailSource.Columns.Add("From");
EmailSource.Columns.Add("Subject");
EmailSource.Columns.Add("DateRecived");
EmailSource.Columns.Add("Body");
}
You are adding rows using listView1.Rows.Add(rowArray) in both the code listings. Is that a typo or you named the GridView like that.
Basically, you are storing the index of the email in the "Tag" property.
listView1.Items.Add(itmp).Tag = i;
You need to make sure that you do the same while adding items to the GridView too.
The DataGridView does not have an "Items" collection. To make it work, you need to bind the DataGridView to a collection of objects. Something like this should get you started:
List<Email> emails = new List<Email>();
for (i = 0; i < bundle.MessageCount; i++)
{
email = bundle.GetEmail(i);
emails.Add(email);
}
dataGridView.ItemsSource = emails;
You should not need to store the row index for each item in a "Tag" object - you can can get the selected index like this:
int selectedIndex = dataGridView.SelectedCells[0].RowIndex;

Categories