c# - DataSet and DataGridView - c#

I have made a basic program to add values to a dataSet and display it to a dataGridView:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DataTable table1 = new DataTable("People");
table1.Columns.Add("id");
table1.Columns.Add("Name");
table1.Columns.Add("Age");
table1.Rows.Add(1, "Jack", 18);
table1.Rows.Add(2, "Tim", 18);
DataSet set = new DataSet("SetPeople");
set.Tables.Add(table1);
dataGridView1.DataSource = set;
dataGridView1.Update();
}
}
When I try it out nothing seems to happen. The dataGridView remains blank. Any idea where I am going wrong?

try this
dataGridView1.DataSource = table1;
you don't need a Ds for just showing a data table in a Gridview

Massimiliano Peluso is correct. The GridView will reference a"Table", but more specifically, when using ADO.NET in a Disconnected fashion you will be filling the GridView with DataColumn objects that are part of a DataTable object. You will also want to bind your dataTable to the GridView.
A bit of Detail:
ADO.Net's DataSet construct allows you to represent your database in a "table" like manner and allow those tables to share references. All of this comes at the cost of additional memory overhead, but if this is not going to be a highly scalable applicaiton and you want to give the users the ability to edit rows without having to go to the database every time, DataSet is a good option.
If you are not using the featuers of DataSet (e.g. table relationships) you can save yourself a little overhead by just using DataTable objects and populating them.
To answer your questions:
A GridView expects to recieve a DataTable as a data source. That table can contain several columns (which will fill the columns of the grid). You can write the following code to specifically access your data table:
dataGridView1.DataSource = set.Tables["table1"]; // or by index if you prefer as there are several overloads.
Additionally, I would bind the data by adding the following line of code after the one perscribed above:
dataGridView1.DataBind();
The fact you are missing your DataBind() method call is part of your issue.
There is a very good example at C sharp corner site: Example

You could also do this:
dataGridView1.DataSource = set;
dataGridView1.DataMember = set.Tables["People"].TableName;
dataGridView1.Update();

Related

C#: Fill DataGridView with DataTable creates empty table

I searched the web and Stack Overflow and found lots of descriptions on how to fill a DataGridView with the content of a DataTable. But still it does not work for me. My DataGridView shows the correct number of columns and rows, but they appear empty.
I use following method:
public void ShowDataInGrid(ref DataTable table)
{
BindingSource sBind = new BindingSource();
dbView.Columns.Clear();
dbView.AutoGenerateColumns = false;
sBind.DataSource = table;
dbView.DataSource = sBind; //Add table to DataGridView
dbView.Columns.Add("Date", "Date");
}
Before this I created a DataGridView of name "dbView" via the designer. I am not even sure, whether I need sBind. Without it I can bind the table directly to dbView, with the same bad result.
I suspect my table is the problem. It origins from a database (SQLite) and has several columns and rows (one of the columns has the name "Date"). It is definately filled with readable data.
I mainly read the table in using following commands (after this I manipulate the data in several different steps, like changing strings and adding numbers...):
string sql = "select * from Bank";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
SQLiteDataReader reader = command.ExecuteReader();
table.Load(reader);
reader.Close();
table.AcceptChanges();
I think the problem might be, that the table entries are stored as objects and not as string, and hence can't be shown. That's why I tried to force the content to be strings with the following change to my table:
DataTable dbTableClone = new DataTable();
dbTableClone.Load(reader);
SQLiteDataReader reader.Close();
dbTableClone.AcceptChanges();
string[] dBHeader = new string[dbTableClone.Columns.Count];
dBHeader = ReadHeaderFromDataTable(dbTableClone); //own funktion, which reads the header
DataTable table;
table.Clear();
//will first create dbTable as empty clone, so I can set DataTyp of each Column
table = dbTableClone.Clone();
for (int col = 0; col > dBHeader.Length; col++) //first set all columns as string
{
dbTable.Columns[col].DataType = typeof(string);
}
foreach (DataRow Row in dbTableClone.Rows)
{
dbTable.ImportRow(Row);
}
This did not help me neither.
Another idea: I found some comments on similar problems, where it got apparently solved with quote: "I designed columns in the VS datagridview designer. Not the column name, but the column DataPropertyName must match with fields in database." Unfortunately I don't seem to be able to do/understand this.
Following you see one row of my input table.
Try fetching and setting to GridView this way
SqlLiteConnection con = new SqlLiteConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=DB.mdf;Integrated Security=True");
con.Open();
SqlLiteDataAdapter adap = new SqlLiteDataAdapter("select * from Bank", con);
DataSet ds = new System.Data.DataSet();
adap.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
Comment everything you've done so far, try this and let me know if this works for you or not. Change connection according to your DB.
I solved the problem.
The DataTable was fine. The problem was the setup of my DataGridView dbView. I set up dbView in the designer and somehow gave it a datasource. Now I set the datasource to "none" (In "DataGridView Tasks") and my data appears as intended.
Thanks to M Adeel Khalid for looking at my stuff. Him assuring to me that my code for the link was right, made me find the solution eventually.
At the end I really only needed to use a single line:
dbView.DataSource = table;

Hiding columns in code generated WPF DataGrid

I got problem with WPF DataGrid.
I try to empty datagrid, add columns and fill it with data from database , and than hide 1 column which is id that user don't need to see.
But when i try, it says that DataGrid columnsCount is 0, even after adding everything at the end of method.
I even tried to hide it in another method after doing 1st one, but still same error.
So my trick to do it is very messy and i want to learn how to do it in better way.
this is my simple code inserting columns etc. to DataGrid:
private void insertSubjects()
{
DataSet dataSet = DBConnect.Instance.getSubjects();
DataTable subjects = new DataTable();
subjects.Columns.Add("id", typeof(int));
subjects.Columns.Add("Przedmiot", typeof(string));
foreach(DataTable table in dataSet.Tables)
{
foreach(DataRow row in table.Rows)
{
subjects.Rows.Add(row["id"], row["name"]);
}
}
subjectsTable.ItemsSource = subjects.DefaultView;
new Thread(new ThreadStart(hideColumns)).Start();
}
My fixing here is new thread that executing method, which execute another one because I need to do it by Dispatcher.Invoke which looks like this:
private void hideColumns()
{
while (subjectsTable.Columns.Count == 0)
{ }
this.Dispatcher.Invoke(hideColumns2);
}
private void hideColumns2()
{
subjectsTable.Columns[0].Visibility = Visibility.Hidden;
}
Problem is when I had on 1 Page or Window , 2 other DataGrids, and if I want to hide columns in both of them, i had to fill them in one method.
I tried to find answer for this, but I failed, and fixed in my way.
The way you've programmed it, I would recommend creating a datacolumn object then inserting that datacolumn object into datatable. With that you can reference the datacolumn using its location.
...
DataTable subjects = new DataTable();
DataColumn idColumn = new DataColumn("id", typeof(int));
// You can set various properties of the DataColumn.
// MSDN Documentation: https://msdn.microsoft.com/en-us/library/x1tyd60z%28v=vs.110%29.aspx
subject.Columns.Add(idColumn);
Now you should be able to access the specific column to reference the actual DataColumn object. It's a pseudo binding trick that I've used in the past.

DataGridView bound with binding list displays blank rows

I have table in my database stored in SQL Server 2012 and through this table I am iterating and adding new object in my binding list. This list is then set as datasource for my DataGridView.
As I understand, the DataGridView should create columns and fill the rows with data, but when I run the build, I only see blank rows. Their count is matching the count of rows in table and I also debugged with breakpoints so I have determined that I really have my datasource filled with data, but I cannot figure those blank rows out.
This is method I use for creating dataset and filling the binding list
public void selectCars()
{
string connString = #"Data Source=POHJOLA\SQLEXPRESS;Initial Catalog=BlueCars;Integrated Security=True";
using (SqlConnection connection = new SqlConnection(connString))
{
connection.Open();
string query = "SELECT * FROM Car ORDER BY CarID ASC";
SqlCommand command = new SqlCommand(query, connection);
using (SqlDataAdapter adapter = new SqlDataAdapter(command))
using (DataSet result = new DataSet())
{
adapter.Fill(result);
foreach (DataRow row in result.Tables[0].Rows)
{
carsList.Add(new Car(Convert.ToInt32(row[0]), row[1].ToString(), row[2].ToString(), row[3].ToString(), Convert.ToDecimal(row[4]),Convert.ToInt32(row[5]),row[6].ToString(),row[7].ToString() ));
}
}
}
}
This is my initialization
public managerCarForm()
{
InitializeComponent();
selectCars();
carsGrid.DataSource = carsList;
}
Also I should probably add, that I created columns manually in designer and set datanameproperty to parameters of the car class
I am not getting any exception or error here..
Thanks very much in advance!
I came across the exact same problem in VB.
I Found out that the solution was this:
(I´ll just write my code in VB you can translate it).
Before setting the DataSource of the grid, you should Clear the grid out.
carsGrid.DataSource = Nothing
carsGrid.Rows.Clear()
carsGrid.Columns.Clear()
Then set your grid DataSource as usual. In My case:
carsGrid.DataSource = GetEmptyObject._Get()
Hope it Helps.
foreach (DataRow row in result.Tables[0].Rows)
{
carsList.Add(new Car(Convert.ToInt32(row[0]), row[1].ToString(), row[2].ToString(), row[3].ToString(), Convert.ToDecimal(row[4]),Convert.ToInt32(row[5]),row[6].ToString(),row[7].ToString() ));
}
Please check your carList by applying a breakpoint after foreach loop to verify it contains at least a single data row. And also check your query.
If your application is an ASP.NET
try to modify your code as below..
public managerCarForm()
{
InitializeComponent();
selectCars();
carsGrid.DataSource = carsList;
carsGrid.Databind();
}
Normally this happens when you have manually added the columns in design time.
Or you have AutoGenerateColumns = false;
If you use AutoGenerateColumns = true; the columns will be/should be auto generated.
To solve this:
Right click on the grid -> Edit Columns.
Go to property: DataPropertyName
Set that to the variable name that you bind to (the table column name in your case).
(You say you have done that, but the value here should exactly match what you have in your list. I have made a DTO class and via a loop I have populated a List of my own and set the names to match the properties of that DTO. This should solve it for you.)

How to Populate the unbounded datagridview from SQL Server database in C#?

In My Project I'm Using Unbounded datagridview with 33 columns for storing the user data in database and I need to populate the datagridview after each and every Insert, Update and Delete.
My Problem is while populating the datagridview with sql server query it shows the column header repeated with data.
my code is given below :
Private Void PopulateGrid()
{
cs.open();
sqladpter da= new sqlcommand("Select * from Customer",cs);
DataTable dt =new datatable();
da.fill(dt);
datagridview.datasource=dt;
datagridview.Refresh();
}
I'll Call This method at the End Of each and every Insert, Update and Delete.
How about Using something simple like datasource and you can have all your CRUD operations
http://msdn.microsoft.com/en-CA/library/dz12d98w(v=vs.100).aspx
try setting DataSource = null before setting new DataSource
datagridview.DataSource = null;
datagridview.DataSource = dt;

How to add new row to datagridview?

I have DataGridView filled with data from datasource (SQL). Now I want to a add new row, but I can't, because new data can't be added to bounded DataGridView...
I was trying to :
dataGridView1.Source = null;
dataGridView1.Rows.Add("1");
but it clears my previous data in table. How to do it, to add new row without deleting previous data?
When you set the DataSource property to null, you are essentially removing all data from the DataGridView (since it doesn't know what to bind to anymore).
You have two options here. The first is to update the underlying data source. Let's assume that it's a DataTable. In this case, you'd do something like:
DataTable dt = dataGridView1.Source as DataTable;
dt.Rows.Add(new object[] { ... });
And then the DataGridView will pick up on the changes (note that if you are not binding to something that doesn't implement the INotifyCollectionChanged interface, you'll have to call the ResetBindings method to get the grid to refresh).
The other option is to let the DataGridView manage the rows. You can do this by manually adding each item using the Add method on the DataGridViewRowCollection returned by the Rows property:
foreach (var item in source)
{
dataGridView1.Rows.Add("1", "2", "3", ...);
}
I wouldn't say the second solution is optimal, but it will work.
Finally, assuming you are binding to a DataTable (or some other materialization of the data from an underlying data source), this doesn't do anything about to updating underlying data source (that would be a separate question).
The short answer is, you don't.
When you set your DataSource to null, you've broken the link between your DataGridView and your data source, so its data won't be persisted. You can't add a row to a bound DataGridView because it's supposed to represent the state of the underlying DataSource; you're effectively asking .net to make your table out of sync with its backing store, defeating the purpose of databinding in the first place.
If you want to add a row to the backing store, you should be adding a row in the DataSource, not in your DataGridView.
maybe you want to do it manually and detailed? Something like this?
DataSet ds = new DataSet();
OleDbDataAdapter adapter = null;
adapter = new OleDbDataAdapter("SELECT * FROM WHERE", conn);
adapter.Fill(ds);
dataGridView1.ColumnCount = 5; //how many columns returns your SQL query? starts with 0
dataGridView1.Columns[0].Name = "COl-1";
dataGridView1.Columns[1].Name = "COl-2";
dataGridView1.Columns[2].Name = "COl-3";
dataGridView1.Columns[3].Name = "COl-4";
dataGridView1.Columns[4].Name = "COl-5";
DataTable dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
dataGridView1.Rows.Add(
(dr["COL_HEADER_NAME1"].ToString()),
(dr["COL_HEADER_NAME2"].ToString()),
(dr["COL_HEADER_NAME3"].ToString()),
(dr["COL_HEADER_NAME4"].ToString()),
(dr["COL_HEADER_NAME5"].ToString()));
}
You just add rows by using add method of rows collection
me.datagridview1.rows.add("first","second","third");
You can add any amount of items with array collection.

Categories