Datagrid won't clear - c#

The datagrid I have made won't let me clear the values. When I attempt to do a datagrid.columns.clear(); then it scrunches the rows together and doesn't display anything more than lines and it still doesn't clear.
I have tried datagrid.items.clear(); as I have used Datagrid.items.add(); to add items to my datagrid. I have tried datagrid.items.refresh(); and setting the datacontext to null. None of this is working.
public void FillDataGridWithCustInfo()
{
CustomerDataGrid.Items.Clear();
CustomerDataGrid.ItemsSource = null;
CustomerDataGrid.Items.Refresh();
int ArrayNum = 0;
Int32 length = CustomerFirstName.Count;
while (length > ArrayNum)
{
CustomerInformation TempCust = new CustomerInformation();
TempCust.FirstName = CustomerFirstName[ArrayNum];
TempCust.MiddleInital = CustomerMiddleInitial[ArrayNum];
TempCust.LastName = CustomerLastName[ArrayNum];
TempCust.TaxClass = CustomerTaxClass[ArrayNum];
TempCust.Email = CustomerEmail[ArrayNum];
CustomerDataGrid.Items.Add(TempCust);
ArrayNum = ArrayNum + 1;
}
}
I want it to clear the datagrid before filling it when I close out of this particular window, but it is currently taking all the data in the datagrid and just adding to it so I am getting duplicates of all the information.

I am not sure is datagrid was use by desktop application , in web application we have a similar object call as gridview which show data as table format. If you want to force clear all row , you can assign an empty or dummy data table , something like below shall do the trick..
GridView1.DataSource = new DataTable();
GridView1.DataBind();
If you want to maintain proper column header and just want to remove row that contain data , make sure you proper structure your datatable..something like this.
DataTable dt = new DataTable();
dt.Columns.Add("Column1", Type.GetType("System.String"));
dt.Columns.Add("Column2", Type.GetType("System.String"));
GridView1.DataSource = dt;
GridView1.DataBind();

Related

DevExpress GridControl mainview not showing information

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.

How to find the DataBase type of a bound DataGridView column

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);

C# Setting value on DataGridComboBoxColumn on bound datagrid using datatables

Using C#
Using SQL I populate a datatable with the results from a query.
then I created a datagrid that uses that datatable as its source.
The datagrid is already configured with a column of type DataGridViewComboBoxColumn.
The Combobox's datasource is another SQL loaded datatable that has two strings for each row. One string is the actual value I need, the second string is the user visible string.
The combobox is populated correctly with the information from the 2nd datatable and the values work as desired. When I save the data out of the datatable I'm getting the correct information for the combobox.
The problem comes into play when I try loading the saved SQL information back into that datagrid. The value doesn't seem to get bound to item the datatable.
Datagrid definition:
dgHeaders.DataSource = dtCSVHeaders;
dgHeaders.Columns["nIndex"].Visible = false;
if (!dgHeaders.Columns.Contains("colType"))
{
DataGridViewComboBoxColumn colType = new DataGridViewComboBoxColumn();
colType.HeaderText = "DB Field";
colType.DropDownWidth = 140;
colType.Width = 140;
colType.DataSource = dtFields;
colType.DataPropertyName = "szDBField";
colType.DisplayMember = "szVisualField";
colType.ValueMember = "szDBField";
colType.Name = "DB Field";
colType.DefaultCellStyle.NullValue = "--Select--";
dgHeaders.Columns.Add(colType);
}
First I tried to set the column name colType to the value I was populating in the dataRow but that didn't seem to work.
Since I couldn't figure out how to get the databinding to work, I decided I'd try to force the cell to the value I wanted so I tried this on the dataload.
... SQL load
foreach (DataRow drRow in dtLoad.Rows)
{
string szColumnName = drRow["szOrgColumnName"].ToString();
string szMatchName = drRow["szMatchColumn"].ToString();
DataRow drAdd = dtCSVHeaders.NewRow();
drAdd["nIndex"] = nLoop;
drAdd["szHeader"] = szColumnName;
dtCSVHeaders.Rows.Add(drAdd);
dgHeaders.Rows[nLoop].Cells[2].Value = szMatchName;
nLoop++;
}
But sadly that still doesn't set the value of the combobox.
I've got no errors or warnings on this code.
I'd prefer to let databinding take control and do its thing without me specifically setting the cell with the value. But if that's what I need to do then so be it...
Hmm, your code (as far as I seen) seem good.
I dont know what exactly is your "dtFields" object, but it should be dataTable.
I did a simple example of how it should be done.
Check it out:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.Columns.Add("column1", "Column name");
dataGridView1.Columns.Add(CreateComboBox());
//adding some rows:
dataGridView1.Rows.Add("a");
dataGridView1.Rows.Add("b");
}
private DataGridViewComboBoxColumn CreateComboBox()
{
DataGridViewComboBoxColumn combo = new DataGridViewComboBoxColumn();
{
combo.Name = "comboColumn";
combo.HeaderText = "Selection";
combo.DataSource = GetDataForComboBox();
combo.DisplayMember = "Name";
combo.ValueMember = "Id";
}
return combo;
}
private DataTable GetDataForComboBox()
{
//this is your method to get the data from database
//in my exmaple I will simply add some example data:
DataTable table = new DataTable("ExampleData");
table.Columns.Add("Id", typeof(int));
table.Columns.Add("Name", typeof(string));
table.Rows.Add(1, "Name 1");
table.Rows.Add(2, "Name 2");
table.Rows.Add(3, "Name 3");
return table;
}
}
This code works, and try to do the same, you only fill dataTable from dataBase. But if you want you can only try this exact code of mine, and you will see it work!
bye

Datagrid with column headers but no rows

I am using WPF Data-grid with auto-generated columns. I am assigning data-table with one column but no rows as Items-source.
public DataTable GetInitData()
{
empDS = new DataSet();
empTbl = new DataTable();
empDS.Tables.Add(empTbl);
dc = new DataColumn("Test");
empDS.Tables[0].Columns.Add(dc);
empDS.AcceptChanges();
return empDS.Tables[0];
}
and I call the method above in the constructor.
public MainWindow()
{
this.InitializeComponent();
this.grdEmp.ItemsSource = this.GetInitData().DefaultView;
}
Screen-shot:
Now when I press F5 and run the code... the Data-grid doesn't show any column. Please guide me, why it is not showing any column. If you need any other information do let me know.
Regards,
Priyank
If you add a single row to your table you will see the column generated. Therefore, I can only suggest this is a limitation (bug?) in the WPF DataGrid. Depending on what you're trying to achieve, you might like to add an empty row to your data first.
public DataTable GetInitData()
{
var empDS = new DataSet();
var empTbl = new DataTable();
empDS.Tables.Add(empTbl);
var dc = new DataColumn("Test");
empDS.Tables[0].Columns.Add(dc);
var row = empDS.Tables[0].NewRow();
//row[0] = "foo";
empDS.Tables[0].Rows.Add(row);
empDS.AcceptChanges();
return empDS.Tables[0];
}

Removing rows from dataGridView-using dataTable

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.

Categories

Resources