In a nutshell: I have a DataSet with multiple DataTables inside, which are connected via multiple DataRelations. I've created a form using databinding on this DataSet, and you could say it is pretty complex.
The scenarios is next: the main purpose of the form is the insertion of a new record. For it to be inserted, various parent-child relations must be set. It all works fine with the databinding, but the problem is next: when user wants to enter a new "child" for one-of-those parent-child relations, new form opens, he enters it, yada yada yada, - and it works. Trouble is - how should I get that new data back to the original form, to appear in parent-child combobox?
One way I know of, is to refresh the entire form; but I am looking for a solution to refresh just the DataTable containing that data. I've tried getting a new DataTable with fresh data from DB, and merging it with DataTable in DataSet, but it doesn't work: "A child row has multiple parents" exception is thrown:
// basically just a Select * using dataadapter,
// nothing programmatically added
DataTable table = tableModule.GetPlainTable();
existingDataSet.Tables["tableName"].Merge(table);
The equivalent example of what I'm trying to do is to have a Order form, with Customer combobox on it. On the right of the combobox, there is a "add" button that opens a new "Add customer" form. Just to mention (maybe it is relevant), inside the DB, "Customers" table is in relation with the "Cities" table, and that data is linked in databindning on the Orders form as well...
EDIT: one solution I can think of is to "manually" loop throughout the new DataTable, and find all rows that are not in the original DataTable inside DataSet, but I'm not sure this would work either ...
Any help / suggestion / explanation / push in the right direction would be greatly appreciated :)
Well, i kind of solved the problem with manual row copy upon insertion in second form... I have created an event with object collection (row item array), and in first form registered a handler on that event, in which I manually add the new row via:
data.Tables["tableName"].Rows.Add(e.RowItems);
after which I call AcceptChanges() on that row to make its state Unchanged, rather than Added...
This solution, although quick-and-dirty, works. The problem is, I think there is a better, more "databinding" philosophy oriented one... :=)
Related
I would like to provide a "Refresh" button on a form containing a DataGridView object bound to a MySQL database. I have gotten screens without columns populated from a query with calculated fields by "new"ing the MySQLCommand, MySQLDataAdapter, MySqlCommandBuilder and DataSet objects and rerunning the query and reloading the binding source to the DataGridView object.
For ones that have calculated columns, this does not work.
Surely, there must be some way to have a DataGridView object reload from the DB.
I am using SharpDevelop C# 5 with .NET framework 4.0, MySQL Community Server 5.3.33 and MySQL Data Connector/.NET V 6.7.4
Any leads much appreciated!
Jesse and Brian,
I am doing WinForms - sorry for not being clear. I have just worked out a solution. First, just executing what was run in the initial load is not enough. I found one must "new" the MySqlCommand, MySQLDataAdapter, MySqlCommandBuilder and DataSet objects, then run the data fetch as in the form load. Also, this cannot be called while doing anything that looks or smells like "editing" or it will throw an exception. I wanted my form to refresh just after edit, so I put a timer on the form and enabled it at the end of the RowValidated event and let the timer call the ReloadGrid routine. Also, if the user is on, say row 822, I found the focus went to row 0 and cell 0, so I save the current row and cell to a point and then set the focus back after the data refresh.
private void BindGrid(){
//retrieve data
//bind
DataGridView.DataSource = dataSource;
DataGridView.DataBind();
}
//call BindGrid() anytime you need to refresh data, for example in a button event click handler
I have a problem and I can't seem to be able to solve it. I thought someone here will be able to help out.
I have a form that has a DataGridView of customers. Now, I want to add several customers to this DataGridView without actually adding them to the database. This is because the client must be able to create a list of clients and when thats done add them all at once.
I have tried this:
string[] array = {"Microsoft", "Redmond", "Something"}
dataGridView.Rows.Add (array);
Now this can't be done because I get an exception saying something in the lines of you cant add rows programatically to a DataGridView that is data bound.
Now I have also read that this can be solved by using a table adapter to insert the rows instead of directly adding them via. a DGV. But this is also not possible because I use custom headers in the DGV because existing data is fetched via JOIN's so if I add them via a TableAdapter I get an exception that the it doesn't match the databases table schema.
Now I am really lost... Anyone know of a (halfway) elegant solution to this problem?
Thank you
Bind your DGV to a BindingList<YourObject>, where YourObject can be a simple class with properties reflecting your database schema. Initially populate the BindingList from the database, and the DGV will automatically add YourObject instances to the list. When you're ready to commit the changes, do so manually from the BindingList.
In order to show those rows, just do a UNION (-like) action before the databinding. Ie get your list of records, add the special ones and then databind.
Updating will require some special action(s) too. But with a total lack of details about your datastructures it's impossible to say what.
I've been trying to figure out for a long time now how to create an interface that can allows users to input several rows of data and pass those entries into an SQL server database all in one shot. I could not get any better ideas so I came up with this (see picture below).
What I envisioned is that the user enters values in the textboxes and hits the "add to list" button. The values are then populated in the list box below with the heading "exhibits lists" and when the add exhibit button is pressed, all values from the list box are passed into the database.
Well, I'm left wondering again if it would be possible to tie these values from the textboxes to the list box and whether I'd be able to pass them into the database.
If it were possible then I'd please love to know how to go about it otherwise I'd be glad if you could recommend a better way for me to handle the situation otherwise I'd have to resolve to data entry one at a time.
I believe there is some useful information from this website that can help solve my problem but I just can't make heads or tails of the article... it seems like I'm almost there and it skids off. Can everyone please read and help me adapt it to my situation? Post below:
http://www.codeproject.com/KB/aspnet/ExtendedGridView.aspx
Yes, it is possible. I have done this twice before.
Check out the "Data Access Tutorials" at http://www.asp.net/web-forms/data for ideas.
Overview
For the user-interface, you want a data-entry-form above a data-grid.
For the back-end, you want a data-adapter (or table-adapter) that loads and saves data to the database in one operation.
You would use a DataSet and DataAdapter to update the database, and manipulate a DataRow for the input and a DataTable for the list-box. Note the list-box is actually a data-grid, repeater, or other control that accepts a DataTable as a DataSource.
The DataAdapter fills the DataSet which contains the DataTable.
The input controls bind to a DataRow created from the DataTable. When the user clicks add-to-list, you add the data-row to the data-table, then create a new data-row for the next item.
When the user clicks add-exhibit, it is a simple matter of using the DataAdapter to update the database. Any changed, deleted, and added data is handled for you.
You could use a transaction to encapsulate all the sql queries you are trying to run, so you can then just 'commit' the transaction in one to the database? Are you still having difficulty with this issue?
Hopefully simple, but can't find any such option.
I have a data table -- has say... 10 rows in it. Some fields on the form are bound to the table.columns respectively by name.
On another form that HAS a grid, as I scroll the grid, the detail fields are refreshed as expected since the grid does some magic to trigger the DataTable record changing event.
WITHOUT using a Data Grid, How can I direct the table to go to a specific row for load/display refresh on the form... ex:
DataTable MyTable = new DataTable();
MyTable = GetResultsFromSQL(); // returns the 10 rows
MyTable.LoadTheDataForRow(3);
MyTable.LoadTheDataForRow(7);
MyTable.LoadTheDataForRow(2);
I know I can use a foreach row in the table, but need explicit use as I don't want to go through all rows, but need specificity to specific ones.
I've looked at the LoadDataRow(), but that appears to be for pushing data back to a server. NOT what I want... I just want to have the "Current" row of the table to be of a specific one...
Thanks
After further research, I've found that a FORM based control "BindingSource" (or derivative) allows this, such as a grid. But, obviously, there's something the .Net engine is doing under the hood to ultimately "Load" a given row into something that ultimately triggers back to the "BindingSource"... The DataTable has RowChanging and RowChanged events which appear to be triggered by OnRowChanging / OnRowChanged delegates, but how can we tell the data table which "row" we want it as the active one.
The form controls can do this for their binding sources, but what is really happening under the hood to trigger these OnRowChanging events... I don't want to re-load a data table, rows, etc, just change what is considered the "Active" row, as in a grid, listbox, combobox, etc.
Have you tried:
MyDataTable.Rows[3];
MyDataTable.Rows[7];
MyDataTable.Rows[2];
I have a DataGridView bound to a LINQ to SQL query expression. I want it to be editable for updates, but for inserts I want users to use separate controls below the grid (textboxes, date pickers, etc - currently not bound to anything). I have an "Add" button that creates an object of the linq to sql entity class based on the values in the controls, and then calls InsertOnSubmit(). When I later call SubmitChanges(), any updates from the grid, and any objects added are all correctly persisted to the database.
My problem is that any new objects are not added to the grid, before or after the call to SubmitChanges(). I would like new objects to be added to the grid as soon as they are created. Also, I only want the controls below the grid to be used for inserting new records, not editing existing records, so I don't think they should be bound to the data source...What is the best way to make this happen?
I did try simply re-setting the DataSource for the grid (ie dataGridView.DataSource = db.<TableName>, which works, but is clumsy because it scrolls to the top of the grid again - I'm sure a better method exists.
(Pls excuse the n00b question, I'm very new to all this .net stuff :P)
The first thing to try is GetNewBindingList(), but this thread: "Linq-SQL canonical editable datagridview sample code" has some thoughts for other scenarios.