How to add child rows in datagrid c#.net windows forms?
I'm not sure if this is what you're asking, but if you want to append rows you're easiest way is to append them to whatever DataSource you're using before you DataBind()
If this wasn't what you're after, please provide more detail.
Usually you bind the datagrid to a dataset. Could you please clarify what you are looking for so that we can get into more detail?
DataTable myDataTable = new DataTable();
DataGridView myGridView = new DataGridView();
myGridView.DataSource = myDataTable;
DataRow row = myDataTable.Rows.Add(1, 2, 3, 4, 5); //This adds the new row
If you are looking for a nested table, you'll have to go with a third-party control. The DataGridView doesn't support it.
Firstly sure your data GridView name and create DataTable
DataTable DT= new DataTable();
then also create DataRow
DataRow row = new DataRow();
and last call the add() function Like this:
DT.Rows.Add("ID","Name","Addr","number");
and don't miss to set source on DataGrideView for Showing data :
DataGrideView.DataSource = DT;
Related
I have a GridControl from Devexpress and I fill the control with a DataRow object. The row is added to the grid but the cells are empty. Here's the code:
DataTable dt = new DataTable();
dt.Columns.Add("Descripcion");
dt.Columns.Add("Cantidad");
dt.Columns.Add("Importe");
gridControl1.DataSource = dt;
clsLineaTicket newLn = new clsLineaTicket("Gin Tonic Beefeater", "1", "9,20");
DataRow dr = dt.NewRow();
dr[0] = newLn.strDescripcion;
dr[1] = newLn.strCantidad;
dr[2] = newLn.strImporte;
dt.Rows.Add(dr);
gridControl1.DataSource = dt;
The code is pretty simple, any idea why is not working? Thank you.
To solve your problem you should set the FieldNames of your GridColumns to the ColumnNames of your DataTable.
But i would strongly recommend you to use List<clsLineaTicket> instead of convert this to DataTable.
At first you already got an object and the Grid can handle this pretty well. So converting this to DataRows seems to be unnecessary. Don't forget any object needs space and a DataRow is still an object.
Further a List<clsLineaTicket>brings you Object access instead of DataRow access. This is more readable and better for refactorings. So you could easily rename a Property via refactoring. But how to rename a column in your DataTable? You access row["ColumnName"] sometimes? Then you are lost because magic string can't be refactored. Let me show small example for better readablity of List<T>:
Think you are in the event for a double click and you would to show the price of your ticket:
//This event is just a dummy and doesn't exists this way
private void grid_click(object sender, EventArgs e)
{
//DataTable access
var row = gridview.GetFocusedRow() as DataRowView;
MessageBox.Show(Convert.ToString(row["Price"]);
//List access
var lineaTicket = gridView.GetFocusedRow() as LineaTicket; //You directly see it's a ticket here
MessageBox.Show(lineaTicket.Price); //You don't need conversion
}
Another goodie is the possibility of Lambda and Linq. You need a SubList with alle Tickets which got a price lower 10$?
List<clsLineaTicket> lowPriceTickets = ticketList.FindAll(ticket=>ticket.Price < 10);
If you using a List make sure your FieldNames correspond to Propertynames. If you want to make the Grid editable you also need to implement setter on your Properties.
Hope this helps.
I am showing a DataGridView control on my form, populating it with a DataTable object through the DataSource property of the control. I set the control to select the entire row when it is selected, and enabled multiselect. All of this works swimmingly.
A user can select multiple rows and click a button. I want to make a new DataTable object with copies of the selected rows and pass that to a Crystal Report.
Is there an efficient means of doing this? It seems the only way is to parse the new rows for the new DataTable from the selected grid cells, which strikes me as relatively ridiculous.
This is my solution to the question "How to get selected Rows as DataTable":
copy structure of original DataTable
copy each row (as a row may exist only in one datatable object)
DataTable selectedRows = (sourceDataGridView.DataSource as DataTable).Clone();
foreach(DataGridViewRow row in sourceDataGridView.SelectedRows) {
selectedRows.Rows.Add((row.DataBoundItem as DataRowView).Row.ItemArray);
}
I've found that the best way to avoid iterating over the DataTable to find the rows you want is to bind to a DataView instead. This way, you can sort and all that other fun stuff you like to do with a DataGridView, and can still get the data you need without manually parsing the underlying DataTable.
Below is a succinct example that should show you everything you need to get a DataRow without searching:
DataGridView dataGridView1 = new DataGridView();
DataTable tb = new DataTable();
DataView dv = tb.AsDataView();
dataGridView1.DataSource = dv;
// Get the row indexes in whatever your favorite manner is.
List<int> selectedRowIndexes = YourGetSelectedRowIndexesMethod();
foreach(int selectedRowIndex in selectedRowIndexes)
DataRow dr = dv[selectedRowIndex].Row;
One quick method to get the selected indexes (just in case you need it):
List<int> indexes = new List<int>();
foreach (DataGridViewRow row in dataGridView1.SelectedRows)
{
indexes.Add(row.Index);
}
I've two DataGridView one very simple and one more complex with different column types.
My idea was to store store the data to XML and also load from the files at restart.
For the simple one it's no problem (dgvAccounts is the DataGridView):
DataTable dtusers = new DataTable("Users");
DataColumn col1 = new DataColumn("ID");
DataColumn col2 = new DataColumn("Key");
dtUsers.Columns.Add(col1);
dtUsers.Columns.Add(col2);
if (File.Exists("user.xml"))
dtUsers.ReadXml("user.xml");
dgvAccounts.DataSource = dtUsers;
....
dtUsers.WriteXml("user.xml");
But on the other DataGridView the DataTable I like to get from the DataSource is ever null (dgvActions is the DataGridView):
DataGridViewTextBoxColumn dgvcolA5 = new DataGridViewTextBoxColumn();
DataGridViewComboBoxColumn dgvcolA6 = new DataGridViewComboBoxColumn();
dgvActions.Columns.Add(dgvcolA5);
dgvActions.Columns.Add(dgvcolA6);
DataTable dtActions = (DataTable)dgvActions.DataSource;
dtActions.WriteXML("actions.xml");
I'd also tried to create a DataTable in advance and add it as dgvActions.DataSource but the result is ever the same.
So please can somebody help me to create a DataTable for the DataGridView or suggest any other way to store and load the data?
Thanks
Andre
What about setting up the datatable first and then setting it as the datasource like you do in the first example(then you wont get the null datatable from the datasource):
DataTable dtActions = new DataTable();
//Set DataTable columns here
dtActions.WriteXML("actions.xml");
dgvActions.DataSource = dtActions;
I am trying to databind a DataTable to an accordion and I have found that If I retrieve the DataTable from a database using a table adapter it binds to the accordion perfectly however what I want to do is create a dummy table (for testing purposes if I don't have access to my database) the code to create the dummy table is below:
DataTable table2 = new DataTable("articletable");
table2.Columns.Add("articleID");
table2.Columns.Add("title");
table2.Columns.Add("content");
DataRow row = table2.NewRow();
row[0] = "1";
row[1] = "article name";
row[2] = "article contents go here";
table2.Rows.Add(row);
When I try to data bind that table however the accordion does not display. I can bind it to a gridview or detailsview but not the accordion.
After 4 hours of banging my head against the wall, I discovered that the DataSource field is VERY picky.
Here's my code:
DataSet ds = new DataSet();
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Branch");
dt.Columns.Add("Officer");
dt.Columns.Add("CustAcct");
dt.Columns.Add("Grade");
dt.Columns.Add("Rate");
dt.Columns.Add("OrigBal");
dt.Columns.Add("BookBal");
dt.Columns.Add("Available");
dt.Columns.Add("Effective");
dt.Columns.Add("Maturity");
dt.Columns.Add("Collateral");
dt.Columns.Add("LoanSource");
dt.Columns.Add("RBCCode");
dt.Rows.Add(new object[] { "James Bond, LLC", 120, "Garrison Neely", "123 3428749020", 35, "6.000", "$24,590", "$13,432",
"$12,659", "12/13/21", "1/30/27", 55, "ILS", "R"});
ds.Tables.Add(dt);
accReportData.DataSourceID = null;
accReportData.DataSource = ds.Tables[0].DefaultView;
accReportData.DataBind();
Turns out that the accordion only likes being bound to a dataset table's defaultview. I tried binding to just a DataTable (dt) and it failed. Even dt.DefaultView failed. Once I added it to a DataSet, it binds like a champ. Very annoying, with lost of wasted time. I know you've probably long-since forgotten this, but I wanted to make it available to future searchers. Accordion.DataSource must be bound to a DataSet.Table.DefaultView to work.
Make sure you specify a type for the columns in the table2.Columns.Add(...)
Also, as seen in the answer below:
https://stackoverflow.com/a/6108163/637903
You can bind the Accordion Control to a DataTableReader constructed from the original DataTable
accReportData.DataSource = new System.Data.DataTableReader(ds.Tables[0]);
accReportData.DataBind();
I have a DataGrid with 5 template columns,
However when I try and add some dynamically created controls into the grid, it fails, as there are no rows.
-Can i add a blank row in and use that? and how?
-Or any other way?
I'm pretty sure you have to bind to a data source. But it's easy enough to create your own DataTable and insert a row into it with some dummy info.
//pseudo code:
DataTable dt = new DataTable();
DataColumn dc = new DataColumn("column1");
dt.Columns.Add(dc);
DataRow dr = dt.NewRow();
dr["column1"] = "value1";
dt.Rows.AddNew(dr);
myDataGrid.DataSource = dt;
myDataGrid.DataBind();
If you are using an unbound DataGridView, you can create new rows and then add them to DataGridView. Your question referred to DataGrid, but you tagged it for DataGridView.
// Sample code to add a new row to an unbound DataGridView
DataGridViewRow YourNewRow = new DataGridViewRow();
YourNewRow.CreateCells(YourDataGridView);
YourNewRow.Cells[0].Value = "Some value";
YourNewRow.Cells[1].Value = "Another value";
YourDataGridView.Rows.Add(YourNewRow);