Add row to existing Datatable - c#

I want to add new row to existing datagridview. There is a problem beacause datagridview is connected to datasource and I can't add row by Rows.Add(). I have tried all commented lines and nothing works. Here is my code:
private void SaveButton_Click(object sender, EventArgs e)
{
if (start_tab == start_picker.ToString("dd-MM-yyyy HH:mm:00") & stop_tab != stop_picker.ToString("dd-MM-yyyy HH:mm:00"))
{
DateTime new_starttime = stop_picker;
DateTime new_stoptime = Convert.ToDateTime(stop_tab);
int new_cycletime = Convert.ToInt32(dataGridView3.Rows[dataGridView3.CurrentRow.Index].Cells["cycle_time"].Value) - Convert.ToInt32(textBox32.Text);
//devents.Rows.Add(new_starttime, new_stoptime, new_cycletime);
//DataTable devents = new DataTable();
//DataTable devents =
//DataRow newRow = devents.NewRow();
//newRow["start_time"] = new_starttime;
//newRow["stop_time"] = new_stoptime;
//newRow["cycle_time"] = new_cycletime;
//devents.Rows.Add(newRow);
dataGridView3.Rows.RemoveAt(dataGridView3.CurrentCell.RowIndex);
dataGridView3.Update();
dataGridView3.Refresh();
}
}
Data to datagridView is loaded from another private void:
private void Openbutton_Click(object sender, EventArgs e)
{
OpenReport();
EventClass eventData = new EventClass();
DataTable devents = eventData.Load_downtimes();
dataGridView3.DataSource = devents;

Adding to the DataTable should actually work.
The question is how you got devents here, it is declared locally in Openbutton_Click below.
You can best get it directly from the dgv (must be cast because DataSource can have various types)
var devents = (DataTable)dataGridView3.DataSource;
DataRow newRow = devents.NewRow();
newRow["start_time"] = new_starttime;
newRow["stop_time"] = new_stoptime;
newRow["cycle_time"] = new_cycletime;
devents.Rows.Add(newRow);

Related

Converting DataSource to DataTable returns null while filtering DataGridView

I'm totally new to Windows Forms and especially DataGridView control.
The problem is when I want to filter DataGridView by a specific column.
In the form load event I bind data to the DataSource of DataGridView like so :
private void Main_Load(object sender, EventArgs e) {
BindingSource bs = new BindingSource();
BindingList<Person> pList = new BindingList<Person> {
new Person {Id = 5, FName = "James", LName = "Allan", Age = 23, Country = "United States"},
// And so on ...
};
bs.DataSource = pList;
dataGridView1.DataSource = bs.DataSource;
}
Then here in click event of button1:
private void button1_Click(object sender, EventArgs e) {
DataTable dt = dataGridView1.DataSource as DataTable;
if (dt != null)
dt.DefaultView.RowFilter = $"FName LIKE '%{textBox1.Text}%'";
}
But the problem is that dt becomes null while dataGridView1.DataSource has value and number of records.
y = x as DataTable;
is not a conversion of your BindingList, but is (usually) equal to
if(x is DataTable)
y = (DataTable)x;
else
y = null;
You have to create a DataTable object by yourself, if you want to use its functionality.
A BindingList cannot be cast to a DataTable.
From How to make a DataTable from DataGridView without any Datasource? you may check this out.
private void button1_Click(object sender, EventArgs e) {
DataTable dt = new DataTable();
foreach(DataGridViewColumn col in dataGridView1.Columns)
{
dt.Columns.Add(col.HeaderText);
}
foreach(DataGridViewRow row in dataGridView1.Rows)
{
DataRow newrow = dt.NewRow();
foreach(DataGridViewCell cell in row.Cells)
{
newrow[cell.ColumnIndex] = cell.Value;
}
dt.Rows.Add(newrow);
}
dt.DefaultView.RowFilter = $"FName LIKE '%{textBox1.Text}%'";
}

columns: Datagridview to Datatable

I am facing this issue, I have datagridview and a datatable.
VPfn_CreateDataGrid();//This fuction creates gridview columns
DataTable invoice_table = (DataTable)invoice_data.DataSource;
now First thing, datagridview is empty when form loads. What I am trying to do is adding data to datagridview via multiple textboxes and combomoxes and for that I am using datatable.
private void btn_add_Click(object sender, EventArgs e)
{
DataRow x = invoice_table.NewRow();
x["serial_number"] = tsr.Text.ToString();
x["item"] = combo_items.SelectedItem.ToString();
x["item_rate"] = tr.Text;
x["item_qty"] = tq.Text;
x["item_unit"] = combo_unit.SelectedItem.ToString();
x["item_vat"] = combo_vat.SelectedItem.ToString();
x["amount"] = ta.Text;
invoice_table.Rows.Add(x);
invoice_data.Refresh();
}
And the error is "Column 'serial_number' does not belong to table"
first you have to create a the data table with the specific column. while your datagridview is empty the DataTable also will be empty.
DataTable invoice_table = (DataTable)invoice_data.DataSource;
infront of this..
while loading your form you can create datatable with the columns.
DataTable invoice_table; //Global
private void load()
{
invoice_table = new DataTable();
invoice_table.Columns.Add("serial_number", typeof(int));
invoice_table.Columns.Add("item");
.....
}
after that
private void btn_add_Click(object sender, EventArgs e)
{
DataRow x = invoice_table.NewRow();
x["serial_number"] = tsr.Text.ToString();
x["item"] = combo_items.SelectedItem.ToString();
x["item_rate"] = tr.Text;
x["item_qty"] = tq.Text;
x["item_unit"] = combo_unit.SelectedItem.ToString();
x["item_vat"] = combo_vat.SelectedItem.ToString();
x["amount"] = ta.Text;
invoice_table.Rows.Add(x);
invoice_data.Refresh();
}
Try this...

Add new empty row to dataGridView bound to DataSet

I am not handy at this. I have a dataGridView bound to SQL by a dataset. All column are generated by the dataset except one column which is replaced by a coded one which is a comboboxColumn.
To avoid new columns being generated while editing a row, I have set the allowUserToAddRows to false. Now I would like to add new empty rows by button click. I have tried in several way without any success.
Updated with full code
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.affitto_saTableAdapter.Fill(this.affitto_SADataSet.affitto_sa);
DataGridViewComboBoxColumn comboCol1 = new DataGridViewComboBoxColumn();
comboCol1.Name = "Periodo Rif.";
List<DateTime> periods = new List<DateTime>() { DateTime.Now.AddMonths(-2), DateTime.Now.AddMonths(-1), DateTime.Now, DateTime.Now.AddMonths(1), DateTime.Now.AddMonths(2) };
//Dates = Dates.OrderBy(x => x).ToList();
List<string> colSource = periods.Select(x => x.ToString("MMM/yyyy")).ToList();
comboCol1.DataSource = colSource;
dataGridView1.Columns.Add(comboCol1);
comboCol1.DataPropertyName = "Periodo";
dataGridView1.Columns["Periodo Rif."].DisplayIndex = 1;
}
private void button1_Click(object sender, EventArgs e)
{
/* DataTable dt = dataGridView1.DataSource as DataTable;
DataRow row = dt.NewRow();
dt.Rows.Add(row);*/
(dataGridView1.DataSource as DataTable).Rows.Add((dataGridView1.DataSource as DataTable).NewRow());
}
}
How can I add a new empty row to such DGV?
Here solution for your problem:
dataGridView1.Rows.AddCopy(myDataGridView1.Rows.Count - 1);
Since your DGV not binded with any of dataSource hence AddCopy of DataGridViewRow will add new row at end of DGV (at Rows.Count - 1).
private void button1_Click(object sender, EventArgs e)
{
this.dataGridView1.Rows.Add();
}

Unable to update comboBox from another comboBox

private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
if (e.TabPage.Name == tabPage2.Name)
{
table = Items.Get();
comboBox1.DataSource = table;
comboBox1.DisplayMember = "Item_ID";
}
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable temp = new DataTable();
string text = comboBox1.SelectedItem.ToString();
temp = Color.Get(text);
comboBox2.DataSource = temp;
comboBox2.DisplayMember = "Color_Name";
comboBox2.ValueMember = "Color_ID";
}
I am trying to populate the comboBox1 as the tabpage open and then populate the comboBox2 based on the selectedText of comboBox1.
comboBox_SelectedIndexChange runs 2 times when tab changes but returns null every times.
Note: I have already appended event handler as the form initializes like,
public Form1()
{
InitializeComponent();
tabControl1.Selected += new TabControlEventHandler(tabControl1_Selected);
comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
table = new DataTable();
s = new Stock();
}
First there is a bug in
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable temp = new DataTable();
string text = comboBox1.SelectedItem.ToString();
temp = Color.Get(text);
comboBox2.DataSource = temp;
comboBox2.DisplayMember = "Color_Name";
comboBox2.ValueMember = "Color_ID";
}
code. You override value for datasource in line
temp = Color.Get(text);
I think it should be like:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable temp = new DataTable();
string text = comboBox1.SelectedItem.ToString();
selectedColor = Color.Get(text);
comboBox2.DataSource = temp;
comboBox2.DisplayMember = "Color_Name";
comboBox2.ValueMember = "Color_ID";
comboBox2.SelectedItem = selectedColor;
}
I don't know contents of DataTable so instead of comboBox2.SelectedItem you may need to set SelectedItem, SelectedText or SelectedValue properties of comboBox2.
Suspicious line here:
string text = comboBox1.SelectedItem.ToString();
You will get text variable filled with "YourNamespace.DataTable". If your function Color.Get(text) is expecting Item_ID of selected item as parameter, then you should change that line of code above to:
string text = ((DataTable)comboBox1.SelectedItem).Item_ID;
I assumed that DataTable is an object that have Item_ID property.
private void tabControl1_Selected(object sender, TabControlEventArgs e)
{
if (e.TabPage.Name == tabPage2.Name)
{
table = Items.Get();
if (table.Rows.Count > 0)
{
//Update comboBox1 using table
comboBox1.DataSource = table;
comboBox1.DisplayMember = "Item_ID";
//Using 1st row and 1st coloumn in function argument to get colors
//Color.Get(string itemID) returns dataTable, which I used for comboBox2 DataSource
comboBox2.DataSource = Color.Get(table.Rows[0].ItemArray[0].ToString());
comboBox2.ValueMember = "Color_ID";
comboBox2.DisplayMember = "Color_Name";
}
}
}

Adding new row to a DataTable

I have a GeidView in my form and I have a button which add new records to the GridView by adding a row to a Datatable and then make this DataTable as the GridContol's Data Source.
The problem is when I add a new record it display in the GridView but when I add another rocord it doesn't display in the GridView, The GridView always contains the first row I added to the DataTable !
So please could you help me to solve this problem ?
This is the source code :
private DataTable recompensesTable;
private void AjoutLivre_Load(object sender, EventArgs e)
{
recompensesTable = MakeRecomponsesTable();
recompenseGridControl.DataSource = recompensesTable;
}
private DataTable MakeRecomponsesTable()
{
DataTable recmpensesTable = new DataTable("Recompenses");
var anneeColumn = new DataColumn();
anneeColumn.DataType = Type.GetType("System.Int32");
anneeColumn.ColumnName = "Année";
recmpensesTable.Columns.Add(anneeColumn);
var prixLiteraireColumn = new DataColumn();
prixLiteraireColumn.DataType = Type.GetType("System.String");
prixLiteraireColumn.ColumnName = "Prix Litéraire";
recmpensesTable.Columns.Add(prixLiteraireColumn);
return recmpensesTable;
}
private void nouveauRecompense_Click(object sender, EventArgs e)
{
DataRow row = recompensesTable.NewRow();
row[0] = ajoutRecompense.KeyWordAnnee;
row[1] = ajoutRecompense.KeyWordPrixLiteraire;
recompensesTable.Rows.Add(row);
recompenseGridControl.DataSource = recompensesTable;
}
In your Page_Load you have recompensesTable = MakeRecomponsesTable();. That overwrites the changes and recreate the datatable values
On page postback, variables are restored to their default values and they need to be recreated. You can use Session to maintain your values
private void AjoutLivre_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
DataTable recompensesTable = MakeRecomponsesTable();
Session["recompensesTable"] = recompensesTable; //Save it to session the first time
recompenseGridControl.DataSource = recompensesTable;
}
}
and retrieve the session preserved value
private void nouveauRecompense_Click(object sender, EventArgs e)
{
DataTable recompensesTable = (DataTable) Session["recompensesTable"]; //retrieve it from session
DataRow row = recompensesTable.NewRow();
row[0] = ajoutRecompense.KeyWordAnnee;
row[1] = ajoutRecompense.KeyWordPrixLiteraire;
recompensesTable.Rows.Add(row);
Session["recompensesTable"] = recompensesTable; //save it back to session
recompenseGridControl.DataSource = recompensesTable;
}
change your
private void AjoutLivre_Load(object sender, EventArgs e)
{
recompensesTable = MakeRecomponsesTable();
recompenseGridControl.DataSource = recompensesTable;
}
To
private void AjoutLivre_Load(object sender, EventArgs e)
{
if(!IsPostback)
recompensesTable = MakeRecomponsesTable();
recompenseGridControl.DataSource = recompensesTable;
}
You also must save the datatable to session
the recmpensesTable is always a new DateTable, you should save it to session for next use.

Categories