Directly manipulating a DataSet - c#

I have a lightweight data-basey kind of thing. Functionally, I'd like to read and write tables out to disk(plus maybe some other info in the future).
I chose to use the DataSet object, paired with the DataGridView control for the IO. The DataSet object can serialize out to disk and back again via the handle XML read/write functions.
However, there does not seem to be an obvious way to add information to the DataView control and have the DataSet object updated. Among other things, the DataGridView won't add a row for me in run-time and won't let me programmatically run the addrow method.
Clearly, I'm missing something.
What am I missing?
This has been suggested:
dataSet1.Tables["mytable"].Rows.Add();
But System.Data.DataRow does not permit direct construction, and I want to add a blank row for the DataGridView to fill in?
edit2: I'm dumb. There's a new row function.
Hmm. I'm wondering if this is just a Wrong Approach.

Don't modify the content of the DataGridView programmatically, modify the DataSet itself instead. It will automatically update the DataGridView if it is databound to the DataSet (using the DataSource and DataMember properties). Changes made by the user in the DataGridView will be automatically reflected in the DataSet.
UPDATE
dataSet1.Tables["mytable"].Rows.Add();
But System.Data.DataRow does not permit direct construction, and I want to add a blank row for the DataGridView to fill in?
You can construct a DataRow manually :
DataRow row = dataSet1.Tables["mytable"].NewRow();
row["column1"] = value1;
row["column2"] = value2;
...
dataSet1.Tables["mytable"].Rows.Add(row);
If you just want a blank row, just don't initialize the fields...
If you have a BindingSource between the DataSet and the DataGridView, call AddNew on the BindingSource. It will add a blank line. You can also use a BindingNavigator control, which handles the calls to the BindingSource methods.

Related

How to add columns to a DataGrid on the fly using WPF in C#

Does anyone know of a way to add columns to a WPF DataGrid on the fly? I'm looking to use a DataGrid in my GUI that will display standard data, and that will also allow the user to add and remove columns. When the user adds a column, the user should be able to specify a value that will be entered on each row of the column. I have used the DataGrid in the past by creating a class with properties and a list of these objects fills out the grid easily, where each object in the list is a row. If I could create a new class on the fly or add a new property on the fly to my existing class, it seems like this would be possible.
I've been looking for a way to add properties to an object on the fly as a possible solution, but I haven't found a way to do this yet, and I don't know if it's a feasible solution. I also haven't found a way to create a new class on the fly and again I don't know if it's possible. I have also tried using a DataTable, but I haven't been able to get that to work either.
Here are more details on what I want to accomplish. A screenshot is included below. The datagrid will be populated with data. The user can then enter a column header and column data. When the "Update Column" button is pressed,if the data field contains "!REMOVE_COL" then the column will be removed if it exists and will not be added if it does not exist. If the column doesn't exist, it will add the column and the value entered in the data field will be added to each row. If the column already exists, then the column data will be updated with the value in the data field.
Haha, nevermind on the screenshot. Apparently I don't have enough rep to post images. :/ You can find the screenshot here:
https://docs.google.com/document/d/1B4UVhVDqFdBbsUMOtMLK2PGTrnKLLux2leo_gas9rdw/edit?usp=sharing
Beware that accessing a WPF DataGrid at run-time it nothing like doing the equivalent for a WinForms DataGridView. Anyway, what you want to do is to create a method which builds and returns a DataSet (which may or may not have data, no data will merely define the column structure)
private DataSet BuildDataGridColumns()
{
// Build the data.
DataSet ds = new DataSet();
DataTable dt = new DataTable();
ds.Tables.Add(dt);
// Add the columns to the DataTable.
DataColumn indexCol = new DataColumn("Key Index", typeof(String));
dt.Columns.Add(indexCol);
DataColumn fileCol = new DataColumn("File Name", typeof(String));
dt.Columns.Add(fileCol);
DataColumn resCol = new DataColumn("Resource Name", typeof(String));
dt.Columns.Add(resCol);
return ds;
}
To create the DataGrid called dataGrid you then can use
dataGrid.ItemsSource = BuildDataGridColumns().Tables[0].AsDataView();
To remove/change the shown columns change the ItemSource, using the above should enable you to accomplish all that you require.
I hope this helps.

C# Commit changes in DataGridView to DataTable

I need an example of code or project with one DataGridView Form and one DataTable so I can edit DataGridView cells and then all the changes are automatically commited into the DataTable. Also how can I create DataTable with the same columns with DataGridView other way that manually?
I tried to create DataGridView and DataTable with the same columns manually and then set the DataGridView.DataSource = DataTable, but data saved into the table are null (anyway number of new rows is correct, but values are invalid).
Tried to google it - all the samples and questions are about savind into DataBase, but I don't need a DB, I just need a simple DataTable and DataGridView binding.
Thanks!
There's no way to create a table automatically from the DataGridView columns (EDIT To refine this: There are ways to automatically create database structures - ORM would be a good keyword here - but I guess that's not what you need). The other way round works well: Create the table and assign it to the DataGridView as its data source. Then the grid should show the respective columns.
"Storing" the values in the data table works only if you have "told" the columns, which field of the underlying table they relate to. That is: You need to create the table columns (it has a name), and when you create the DataGridView column, you need to assign the column name to the DataPropertyName property of the column.
Easiest way for you: Create a typed dataset (use the "Add to project" dialog to add a new "DataSet"), manually create a table in the dataset's designer, drag an instance of your dataset to the form and assign this as the data source to your DataGridView. Everything else should appear automatically.
I hope you this links from codeproject might help:
http://www.codeproject.com/Questions/80935/save-datagrid-data-to-database
http://www.codeproject.com/Articles/12846/Auto-Saving-DataGridView-Rows-to-a-SQL-Server-Data
If your DataTable is set as the DataSource for the dataGridView, the contents in the dataGridView will reflect the data in the DataTable and vice versa. Therefore, if you make changes to the dataGridView, those changes are already in the DataTable.
Convert DatagridView To DataTable.
In C#.NET:
DataTable dt = ((DataView)this.dataGridView1.DataSource).Table;
VB.NET:
Dim dt As DataTable = CType(Me.dataGridView1.DataSource,DataView).Table

How to reuse DataTable for different data source in C#?

I have a DataTable (displayed via a DataGridView) and want to reuse it to manually fill in different data. So the workflow is:
Every time I need to refill the DataTable, I do:
Unhook the DataTable from the DataGridView.
Clear DataTable content.
Manually add DataColumns and DataRows to the DataTable.
Hook the DataTable again with the DataGridView.
To achieve step 0, I simply do: DataGridView.DataSource = null.
To achieve step 1, I call DataTable.Clear(), DataTable.Rows.Clear() and DataTable.Columns.Clear().
To achieve step 3, I call DataGridView.DataSource = DataTable.
Step 2 is done in normal way and I skip the code.
Whenever the DataGridView is updated with a new content, if I click DataGridView column to sort, the next time when the DataTable is updated, I will get a null reference exception in step 2 when I try to add new rows. But if I never click DataGridView column to sort, all works fine.
I guess it has something to do with the sorting. But I have no idea what causes the null reference exception. Is it possible that the DataTable tries to search some keys in old content but couldn't find it? It cannot find the old content because of step 1 of course. What is the right way of clearing old DataTable content so it never refers the old content when I fill in new stuff?
Thanks.
The DataGridView's databinding is tied to the table (through a DataView); you cannot pull the table out from under it and expect it to continue working.
When you sort by a column, the grid asks the DataView to change its sort order, which fails because the column doesn't exist anymoe.
You should create a new DataTable.

Customise a bound datagridview

Howdy, using vs2008 winforms.
I want to be able to use a slightly customised datagridview but cant think of a way to do it.
i have
1. a sqldataadaptor fill a dataset
2. a binding source bound to the dataset
3 a datagridview with the bindingsource set as the datasource.
I want the binding to allow sync between the dataset and datagridview, so i can edit data and then update to database with sqldataadaptor. update.
I want to show some custom columns that are calculated results.
And i want to show a final bottom row that is totals of all the columns in the DVG.
My problem is once the DGV is bound i cant add a custom column or row, it wont let me.
I know i could add it directly to the dataset that is the underlying datasource but then by changing the structure of the dataset i cant update to a database once edits have taken place.
or can i ???
Can someone tell me how i can add my custom columns and a final total row to a bound DGV.
Also while im here, if i click on the top of a column to sort on it, in a bound DGV, will it also re-sort the underlying dataset, so i i edit things will still stay synced ?
thanks in advance for any help
Yes, you can.
The adapter does not care about structure. It only cares about column names used in the Select/Insert/Update/Delete commands. You can add custom columns, expression columns, columns for subtotals, columns for totals, or whatever you need. Even change the order of the columns. I do advise adding a sort column, so you can keep the custom rows in the proper place when you or the user sorts.
You can do the same thing for custom rows. When you update through the adapter, you handle the RowUpdating event and set the SqlRowUpdatingEventArgs.Status to SkipCurrentRow for these custom rows. I strongly advise creating a row type column so you know which rows to skip when updating. (You can also use the sort column's value as a key to skip rows.)
There are a couple of articles on MSDN or KB that illustrate how to add total rows.
"How to sum the fields in a Windows Forms DataGrid control and then display the calculated totals in a footer by using Visual Basic .NET" at http://support.microsoft.com/kb/836672.
In my experience, manipulate the data table first before binding. Do what you need to do in order to support the grid and the grid's interface. It is okay to manipulate the data, add/change/remove columns and rows, then rebind when needed.
To be able to add additional unbound columns to your DataGridView you could also set its AutoGenerateColumns property to false and then add custom columns with the following method:
dataGridView->Columns->Add(...)
To calculate the contents of the unbound columns you can handle the CellValueNeeded and CellValuePushed events but you must set the DataGridView into 'virtual mode' by setting the VirtualMode property to true in order for the eventhandlers to be invoked.
Hope this helps a little....

How do I create a DataGrid in C#?

I want to add a DataGrid to a Form. When the program executes, the user enters values and I use those values in the problem. I need a similar implementation for a table with two columns and when the user enters values I use them to for calculation in the program.
There is no requirement to save these values to a database, they are just going to be used in the program.
How do I do this in C#?
In a winforms environment, you can bind strongly typed collections as the datasource; Each property of the objects in the collection makes a column (Strictly speaking, I believe it works out the properties for the type that the collection returns, rather than the individual items in it)
If you are writing a WinForms App then you can use a DataTable to store the data and a DataGridView to display it. Simply create the DataTable:
dataTable = new DataTable();
Create the columns you need programatically:
var columnSpec = new DataColumn();
columSpec.DataType = typeof(decimal); // If it holds a decimal
columSpec.ColumnName = "Interest Rate";
dataTable.Columns.Add(columnSpec);
Add the DataGridView to the form using the Designer - but don't and then once the table has been created bind it to the grid using:
dataGridView.DataSource = dataTable;
You can set the properties on the grid from the designer view.
I have done this in a read-only case where the DataTable is populated from the program and just displayed it. All the user can do is resize, reorder or set the visibility on the columns. To add new rows you'll need to hook into the RowsAdded event
Re-wording Rowland Shaw
You need not have a database to bind to the datagrid. If you have the data filled in a strongly typed or a generic collection you can bind the datagrid to the collection. The datagrid will fill the data from the collection.
It will take the property names as the columns, and the rows will display as per the rows in the collection.
If you want user input, then I think you should consider using a better grid control. The datagrid is not suitable for this purpose. I dont' remember if flexgrid (the ocx one) has been redone for .Net.
You can use a datagridview and build a datatable and add columns through your code and set the datatasource of your datagridview as this datatable and set AllowUserToAddRows in properties window of Dataggridview to true ( true is the default value ).
If you want to make the calculation after a full ro update is made then you can use RowPrePaint event or if you want the calculation to be made after the data in each cell gets updated then you can use the CurrentCellChanged event of the datagridview.
Hope this helps....

Categories

Resources