I have the following set of codes for adding values to my DataGridView through DataTable as my datasource. However, it keeps on giving me the error "Child list for field tbl_main cannot be created". Anybody can help me identify the problem?
dgvMySchedule.Columns.Clear();
dgvMySchedule.Rows.Clear();
dgvMySchedule.ClearSelection();
dataSet.Tables.Add(tbl_main);
dgvMySchedule.DataSource = dataSet;
dgvMySchedule.DataMember = "tbl_main";
tbl_main.Columns.Add("TIME");
tbl_main.Columns.Add("CLASS");
DataRow row;
dgvMySchedule.RowTemplate.Height = 8;
for (int i = 0; i <= 71; i++)
{
row = tbl_main.NewRow();
row["TIME"] = i;
row["CLASS"] = i;
tbl_main.Rows.Add(row);
}
It looks like your tbl_main is unnamed, or it has a different name than "tbl_main". There are three possible solutions:
Remove the DataSet, instead use dgvMySchedule.DataSource = tbl_main;
If you need/want the DataSet, add tbl_main.TableName = "tbl_main";
If you need/want the DataSet, remove the line saying dgvMySchedule.DataMember = "tbl_main" (the grid will then automatically use the one DataTable present).
I finally realized my mistake. I forgot to initialize my datatable during declaration. I used DataTable tbl_main = new DataTable(); instead of DataTable tbl_main = new DataTable("tbl_main"); The changes pretty much answered my concern. Thank you!
I had this problem using binding in winforms.
I had set binding to a non existent field name.
Related
I have a DataTable, dtHOURS, that consists of two columns of data passed from an SQL database and I am trying to include a third column that consists of calculated values within the array, hours. I've looked at many similar asked questions, but none of the solutions seem to work in my case. I've confirmed that the correct values are being stored in the array, but I can't seem to populate those values within column "Total Hours". All the row data comes out blank for this column.
Any help would be appreciated.
Thank you in advance.
//Create new column and row for the "Total Hours" in data table
DataColumn TotalHoursCol;
DataRow TotalHoursRow;
// Create new DataColumn, set DataType,
// ColumnName and add to DataTable.
TotalHoursCol = new DataColumn();
TotalHoursCol.DataType = System.Type.GetType("System.Double");
TotalHoursCol.ColumnName = "Total Hours";
// Add the Column to the Table.
dtHOURS.Columns.Add(TotalHoursCol);
//This loop calculates the total hours for all jobs and adds them to the data table
for (int i = 1; i < numberOfRecordsHours; i++)
{
//Console.WriteLine(dtHOURS.Rows[i]["ID"]);
//Console.WriteLine(dtHOURS.Rows[i]["ACT_RUN_HRS"]);
if ((Convert.ToString(dtHOURS.Rows[i]["ID"])) == (Convert.ToString(dtHOURS.Rows[i-1]["ID"])))
{
hours[i] = (Convert.ToDouble(dtHOURS.Rows[i]["ACT_RUN_HRS"])) + (hours[i-1]);
//Console.WriteLine(hours[i]);
}
else
{
hours[i] = 0;
//Console.WriteLine("NEW JOB");
}
TotalHoursRow = dtHOURS.NewRow();
TotalHoursRow["Total Hours"] = hours[i];
dtHOURS.Rows.Add(TotalHoursRow);
//Console.WriteLine(dtHOURS.Rows[i]["Total Hours"]);
}
If I am understanding the problem correctly, it looks like you are adding a new row instead of assigning to your new column.
Instead of
TotalHoursRow = dtHOURS.NewRow();
TotalHoursRow["Total Hours"] = hours[i];
dtHOURS.Rows.Add(TotalHoursRow);
Just put
dtHOURS.Rows[i]["Total Hours"] = hours[i];
I need to know the original type of each column in my DataGridView.
It is bound with a dynamic SQL select, say, "SELECT * FROM artists;"
I want to add a form view of the data above the grid and am programmtically creating Labels and TextBoxes and then some to hold the fields. I add them to a FlowLayoutPanel but I would like to adapt the sizes, especially the multiline property and the height to accomodate long comment and description fields of say 200-500 characters.
All I found when looking into the text columns was datatype string.
I know I can look up the columns by querying the systables, but it would be nice to find the original datatype a bit closer than that; also I'm using MYSQL atm, and a solution that doesn't need to query the database would hopefully also be DBMS independent.
Edit 1
I fill the DGV with nothing fancy:
DBDA = new MySqlDataAdapter(sql, DBC);
MySqlCommandBuilder cb = new MySqlCommandBuilder(DBDA);
DBDS = new DataSet(ddlb_tables.Text);
DBDA.FillSchema(DBDS, SchemaType.Mapped); //<- This was the missing piece of code!!
DBDA.Fill(DBDS, ddlb_tables.Text);
dataGridView1.DataSource = DBDS;
dataGridView1.DataMember = ddlb_tables.Text;
Edit 2
With the help of the accepted answer (DBDA.MissingSchemaAction) I could solve my problem. Here is the resulting function in its first, raw version:
public int getColumnSize(DataGridViewColumn dc)
{
try
{
DataGridView DGV = dc.DataGridView;
DataSet DS = (DataSet)DGV.DataSource;
DataTable DT = DS.Tables[0];
DataColumn DC = DT.Columns[dc.Name];
return DC.MaxLength;
} catch { }
return -1;
}
Not getting the original type is not a problem, as long as I know the length of the fields.
use the DataSet instead DataGrid:
foreach (DataColumn col in DBDS[ddlb_tables.Text].Text.Columns)
{
if (col.DataType == typeof(string))
{
var len = col.MaxLenght;
...
}
}
EDIT:
You may need to add the following line before filling:
DBDA.MissingSchemaAction = MissingSchemaAction.AddWithKey;
Source: The DataAdapter.Fill method does not set all of the properties of the DataTable and DataColumn objects
EDIT 2:
Or for result sets without a key:
DBDA.FillSchema(DBDS, SchemaType.Source);
Or:
DBDA.FillSchema(DBDS, SchemaType.Mapped);
I used a CheckedComboBoxEdit control. It is filled by a dataTable. And I checked an item programatically.The following picture shows the output:
It shows that, no items are selected in drop down menu. I did not understand the problem.
Edit: I found the source of the problem. However I do not know, how can I fix this and why it causes the problem.
My code:
rHOP rGetir = new rHOP();
DevExpress.XtraEditors.Repository.RepositoryItemCheckedComboBoxEdit propertiesBaslattigiSurecler = cceBaslattigiSurecler.Properties;
DataTable dt = rGetir.GetirSurecTanim(0, 0);
dt.Columns.Add("Deger", typeof(string));
for (int i = 0; i < dt.Rows.Count; i++)
dt.Rows[i]["Deger"] = dt.Rows[i]["Süreç No"].ToString()
+ "," + dt.Rows[i]["Sürüm"].ToString();
propertiesBaslattigiSurecler.DataSource = dt;
propertiesBaslattigiSurecler.DisplayMember = "Süreç Ad";
propertiesBaslattigiSurecler.ValueMember = "Deger"; // this line causes the problem
cceBaslattigiSurecler.SetEditValue(null);
The dataTable dt has three columns as "Süreç Ad", "Süreç No", "Süreç Ack". Then I added "Deger" column to the dataTable. When I set the ValueMember property to "Deger" column, the problem occurs. When I set the ValueMember property to another column, it works correctly.
Following Error in this line.
datagridview1.Rows.Clear()
but this line gives error:
Cannot clear this list.
I also had similiar problem when I try to clear DataSource of a DataGridView after I had binded it to a DataTable with:
DataTable DT = ... ; // fill it
datagridview1.DataSource = DT;
when I try to clear it's rows later with the following code:
datagridview1.DataSource = null
I get this error:
ERROR: Object reference not set to an instance of an object
This object reference ERROR problem already solved in here. But I managed to solve my own problem (clearing DataGridView rows) with this code:
DataTable DT = (DataTable)datagridview1.DataSource;
if (DT != null)
DT.Clear();
I know that this question was asked a very long time ago, but I hope my solution would solve someone problems.
Is your DataGridView bound to a DataSource, i think thats why its not allowing you to clear it since its bound to an underlying DataTable or List.
you could try setting the DataSource Property to null
datagridview1.DataSource = null; for clearing
private void button_Limpar_Click(object sender, EventArgs e)
{
DataTable DT = (DataTable)dataGridView_Cidade.DataSource;
if (DT != null)
DT.Clear();
}
#endregion
Simply add this line at beginning of your event:
dgv_nameOfGridView.DataSource=false;
Now every time you click it will erase the dgv..
You have to Clear datasource not datagridview rows.
datagridview1.DataSource = null;
Another way is
1) Dont assign direct datasource to gridview.
add rows from datatable to gridview
foreach (DataRow row in dataTable.Rows)
{
var dataGridRow = new DataGridViewRow();
dataGridRow.CreateCells(datagridview1);
for (int i = 0; i < row.ItemArray.Length; i++)
{
dataGridRow.Cells[i].Value = row.ItemArray[i];
}
datagridview1.Rows.Add(dataGridRow);
}
then use
datagridview1.Rows.Clear()
You can use this simple method:
First clear your DataTable and then refresh your DataGridView
dataTable.Clear();
dataGridView.Refresh();
Hope this help
Easy solution is to clear the DataSet.
ds.Clear();
Since you are using a bound grid, have you tried to call your loading
function twice and verified that the data is not doubling?
Since it is bound, loading twice ought to not duplicate the data.
http://www.vbforums.com/showpost.php?s=aa5f116586c00a2d9ea15e3727fc5c2f&p=2841192&postcount=9
First clear DataSource and then clear DataGridView
in VB
datagridview1.DataSource = Nothing
datagridview1.Rows.Clear()
hope help
If you load your DataGridView with a parameter, you can send an empty parameter to it. This will clear your DataGridView without having to set its DataSet to null.
For example, I load my DataGridView with a Code, when I fill a TextBox.
this.dataTable1TableAdapter.Fill(this.ds_MyDataSet.DataTable1, TextBox1.Text);
If I want to clear its content, then
this.dataTable1TableAdapter.Fill(this.ds_MyDataSet.DataTable1, "");
Here we are 8 years later.
Although
datagridview1.DataSource = null;
is a satisfactory answer for most, for me this removes all customizations I've added to the columns in design view. So hidden columns appears if I want to clear out the rows.
So rather than clear out rows:
datagridview1.Rows.Clear()
Clear out the DataTable or DataView that you used to set up the DataGridView. Note you don't have to check if something is null nor worry about Object not set to reference errors.
So here's how I did mine:
//Populate the datagridview
DataTable _DT = new DataTable();
BindingSource _BS = new BindingSource();
//Initially fill up your datatable with stuff
//You can call this method again if data needed to be changed
public void fillDT(int id) {
_DT = fillUpDataTableWithStuffFromDB(id);
_BS.DataSource = _DT.DefaultView;
datagridview1.DataSource = _BS;
_BS.ResetBindings(false);
}
//You can use this method to mimic the functionality above
//But rather fetching data, just clear out the datatable and pass it in
public void clearDT() {
_DT.Clear();
datagridview1.DataSource = _DT.DefaultView;
datagridview1.Refresh();
}
As you can see above, I just cleared out the datatable, and passed that into the datagrid. This kept all my properties I set on the datagridview column.
foreach (DataGridViewRow item in this.datagridview.Rows)
{
datagridview.Rows.RemoveAt(item.Index);
}
I had the same problem I tried with many solutions.
In the end I realized that we can't clear the DataGridView if we use it's property "DGV.Datasource" because DGV takes its data from the dataset so you need to clear the DataTable rows
Dataset.Tables["TableName"].Rows.Clear();
If you use this function in the Load of the Form you need to add a condition
if (DataSet.Tables["TableName"] !=null)
Dataset.Tables["TableName"].Rows.Clear();
or you will get this error
Object reference not set to an instance of an object.
I am trying to remove all the rows to reload them (I need to remove all rows) For some reason its not removing them from my datagridview (tho its not adding any extra either) nothing is happening. I have tried many different methods, I know I have done this in the past. (maybe because its end of the day)
Here is my code trying a whole bunch of removes
private void loadMSXGridView()
{
BindingSource bs = new BindingSource();
dgv.DataSource = null;
dgv.Refresh();
bs.DataSource = GetTable();
dgv.DataSource = bs;
dgv.Columns[0].Width = 391;
dgv.Columns[1].Width = 30;
}
private DataTable GetTable()
{
DataTable t = new DataTable();
t.Rows.Clear();
t.AcceptChanges();
t.Columns.Add("Accounting Line", typeof(string));
t.Columns.Add("#", typeof(string));
foreach (AMAPnr.RemarkElement re in AMAPnr._RemarkElements)
{
if (re.ElementID == "RM" && re.FreeFlow.StartsWith("*MS"))
{
DataGridViewCell gridCellText;
DataGridViewCell gridCellElement;
gridCellText = new DataGridViewTextBoxCell();
gridCellText.Value = re.FreeFlow;
gridCellElement = new DataGridViewTextBoxCell();
gridCellElement.Value = re.ElementNo.ToString();
t.Rows.Add(gridCellText.Value, gridCellElement.Value);
}
}
return t;
}
My delete button calls loadMSXGridView, I only need to refresh everything because the items in my datagridview are associated to an element number, which won't remain the same
Initially, you are data-binding:
dgv.DataSource = GetTable();
you should then continue data-binding; either tell the table to clear itself (and repopulate the data), or just assign a different data-table to dgv.DataSource.
In my limited data binding experience it is not easy to edit a data source. You should handle your data edits using one of the row binding or other events. However if you want to edit a datasource you basically have to clone the structure, then import the rows. So in this sense you should actually go back to your datasource and select exactly what you want.
However..
If you want to filter / edit your data here is how you can do it:
DataSet ds1 = [Your Data Source]
DataSet ds2 = new DataSet();
ds2 = ds1.Clone();
for (int i = 0; i < ds1.Tables[0].Rows.Count; i++)
{
if (ds1.Tables[0].Rows[i].ItemArray[0].ToString() != "SomeValue")
{
ds2.Tables[0].ImportRow(ds1.Tables[0].Rows[i]);
}
}
ds1 = ds2;
If you simply just want to add a different datatable as the datasource, then do:
datagridview.DataSource = datatable;
datagridview.Invalidate();
That should work, as I have just done the exact same thing on a project i'm working on at the minute :)
My fault, everything worked after running a throughough debug I found
The remarks elements were not being deleted, thus it was getting deleted by adding the same items back in. I remove the items from the RemarkElement section and it works, thanks for your help everyone!
I would suggest to set the DataSource of your DataGridView to a BindingSource and change the DataSource of the BindingSource instead:
var table1 = GetDataTable();
var bindingSource1 = new BindingSource(table1, null);
dataGridView1.DataSource = bindingSource1;
// after reload
var table2 = GetDataTable();
bindingSource1.DataSource = table2;
that solves most problems, since you don't have to worry about how your data is bound.