I would like to insert into a database from SQL Server with a BindingSource in Windows Forms and VB.
Right now I have a DataTable with its DataTableAdapter in 'Details' mode and a bunch of TextBoxs (and other Controls, but that isn't the issue) whose Text attributes are bound to my BindingSource.
If I fill the TableAdapter XDataTableAdapter.Fill(XDataSet.XTable) those TextBoxs receive the data from the first entry, and BindingSource has every row from the db and every column value, so BindingSource and the adapters work.
Instead of modifying the existing entries I would like to insert a new one with its contents as those linked in the various TextBoxs.
I was told I should then use XBindingSource.AddNew() and lastly, once I am certain of the data in the TextBoxs XDataTableAdapter.Update(XDataSet.XTable).
The problem is, before I execute AddNew my BindingSource can read what is being written. But once I reach AddNew, the count of BindingSource increments in 1, but the Items of its current row are empty, regardless of the content of the TextBoxs.
So the issue is, after BindingSource.AddNew, the rows from the db contain its values correctly, but the current new one has them empty, without reading from the bindingsources of the textboxes. Is there any instruction for BindingSource to execute so it knows that the new row should read the textboxs?
So when, I reach the Update instruction, the new row is empty so it doesn't change anything.
My question is, how can I tell BindingSource that the new current row is what is being written in the TextBoxs.
I just wanted to insert into my database straight from the controls bindings, without having to link each one manually.
I'll correct a few misconceptions if I may; hopefully it'll help you understand what's going on:
Right now I have a DataTable with its DataTableAdapter in 'Details' mode and a bunch of TextBoxs (and other Controls, but that isn't the issue) whose Text attributes are bound to my BindingSource.
You have a TableAdapter - a generic name for the type of thing VS generates for you when you use this method of accessing a database. Be sure to call them TableAdapters, as that's what we know them by, and they're distinct from DataAdapters, which are a more basic thing for accessing databases. People might be confused as to which you mean if you call it a DataTableAdapter
TableAdapters don't have a "Details" mode. "Details" refers to something you did in the Data Sources window - you changed from datagrid to details and then dragged a node representing a datatable onto the form, and a bunch of textboxes etc appeared, along with a tableadapter, dataset, bindingsource, bindingnavigator and maybe a tableadaptermanager. At this point you could do nothing else except run the program and it will be able to save new data. "Details" means "create a bunch of textboxes rather than a datagrid" and is a function of the datasources window only
If I fill the TableAdapter XDataTableAdapter.Fill(XDataSet.XTable) those TextBoxs receive the data from the first entry, and BindingSource has every row from the db and every column value, so BindingSource and the adapters work.
Again, a slight terminology tweak: You don't fill a TableAdapter, a TableAdapter is a device that fills a datatable. The datatable that it fills lives inside a dataset. The bindingsource is bound (connected) to the datatable. The datatable holds a cache of local data downloaded from the database. Textboxes are bound to the bindingsource. Because a textbox can only show one record at a time, the bindingsource maintains knowledge of what is the "current" record. The bindingnavigator (a toolbar) moves the bindingsource's current pointer, which causes the textboxes to change values. You use the textboxes to change the values or add new ones. This causes the bindingsource to transmit changes through to the underlying datatable, affecting whatever row it considers to be the "current" row. At some point you save the changed datatable back to the db. The underlying datatable rows change from Unchanged (the state they have when downloaded) to Modified. This is how the tableadapter knows to run the SQL UPDATE query - it looks at the state of the row
Instead of modifying the existing entries I would like to insert a new one with its contents as those linked in the various TextBoxs. I was told I should then use XBindingSource.AddNew() and lastly, once I am certain of the data in the TextBoxs XDataTableAdapter.Update(XDataSet.XTable).
You can indeed do this. The bindingnavigator has a + button on it that does this, or you can write some other code that calls AddNew() on the bindingsource. When you call AddNew the bindingsource makes a new data row but it doesn't add anything to the datatable immediately. When you tell a bindingsource to AddNew, it will switch to pointing its current at the new item, all the textboxes go blank, and you can type the new details into them. These details will go into the new temporary row but remember that that row is not a part of the underlying datatable yet
The problem is, before I execute AddNew my BindingSource can read what is being written. But once I reach AddNew, the count of BindingSource increments in 1, but the Items of its current row are empty, regardless of the content of the TextBoxs.
It's not a problem, it's by design. It's only the same as opening Word and writing a document - it's not saved on your hard disk yet, it's just in memory. You need to do something to commit it to hard disk, just like you need to do something to a bindingsource to make it commit the new item into the underlying data store (the datatable)
To make it commit you need to do something like: navigating to another record, or calling EndEdit() on the bindingsource. At this point it adds the row to the underlying table and this new row has a RowState of Added - this means that when the tableadapter runs its Update (which should really be called Save) it will use the built in SQL INSERT query to save the row; because it's Added/new/needs inserting into the DB
So the issue is, after BindingSource.AddNew, the rows from the db contain its values correctly, but the current new one has them empty, without reading from the bindingsources of the textboxes. Is there any instruction for BindingSource to execute so it knows that the new row should read the textboxs?
I think you're doing things in the wrong order. You're supposed to AddNew, then fill in the text boxes with the new data, then do something like navigate away from the new data, or hit save or some other button that does a Validate()/EndEdit() on the form/the bindingsource. The committing of the new row happens upon EndEdit() of the bindingsource; that puts the row into the table but it still isn't saved to the db at this point. To save, one must call tableadapter.Update(theTable)
It might seem a bit odd, but again, think of it like MS Word. You could open an existing document, then you can do Ctrl+N for a new document, then you write the document. The new document isn't saved to disk yet.
In tableadapter terms the process is the same: You could download an existing database table, then you can do AddNew for a new row, then you write the new row details. The new row isn't saved to database yet.
I'm displaying some read only data in a WPF DataGrid. The amount of data doesn't always fill the available space, and sometimes there is no data to show at all and the DataGrid is empty. However, I'd like the space to look like a spreadsheet regardless of how much data I've got. Is there a way to pad the DataGrid out with blank rows to make it look a bit more like a spreadsheet?
If your are binding data grid with a list fill class containing empty value in there property with which column is binded as per your requirement if the required data not come.
if required data come overwrite it.
I have an app in C# WPF with an existing .rdlc file added to a ReportViewer. The report already has datasets. Here is a printscreen: link. Now, I have a DataGrid that's bound to an ObservableCollection. How can I pass data from the collection to the fields of the dataset? The parts of the items of the ObservableCollection have the same type as the fields of the datasets but have different names. So I want the user to be able to select a single row from the DataGrid and the records of this row (parts of an item of the ObservableCollection) to fill the appropriate fields of the dataset thus showing a populated report in my ReportViewer. And whenever the user selects a different row, the data in the report should change accordingly. I hope I've been clear. I've read about IEnumerable and List<T> set as datasource but I don't get that. I just want to overwrite the fields of my dataset as if they were parts of a structure or a class and then present them in the formatted report. Can this be done in a similar, simple way? Because I don't know why I would want to take my item from the ObservableCollection and make a List<> out of it. But in case I chose this option should the items of the List<> have the same name and type as the fields in the dataset?
Thank you for your answer in advance!
I was wondering what the best way was to create an empty datagrid.
For example after you have hit new in excel, You have a grid with empty rows and columns.
I am using c# with WPF and .net 4.0.
Thank you.
As the comments have suggested, a datagrid is not a spreadsheet, but a method to display / edit existing data. That said if you want something similar, feel free to populate a collection with default / 'empty' objects and bind that to your grid. It just means that after working with the data, you will have to define a method to capture only the edited rows. This still means that the column-bound properties of your class need to be known ahead of time.
A DataGrid is used to display a collection. If you want to create an individual row DataGrid is not really the right tool. You could but a single empty row in the DataGrid using a collection of only on row. There is a lot of guidance on Master Detail on MSDN. If you don't know how many columns at design time you could used a DataGrid to turn the row vertical with column 1 as name and column as value so now you have one record but with a collection of fields.
I have 3 ListViews in a WPF Grid Column, one each for customers, products, and vendors.
They each get data from LINQs to separate SS2005 queries in the same DB.
The lists are populated when a user enters text in a TextBox.
The LINQ query code uses as startswith() function that reads the user entry and returns a smaller list to the ListView.
When the code is run, each ListView is populated properly.
However, the Products list doesn't display the entries.
I attached a call to a MessageBox to the selection event of the ListItem and the message box correctly displays the product.
The single difference between the two working lists and the bad one is the query that calls the bad one returns a single field from the DB and the others return two fields, a text field and an integer ID field.
I'm at a loss.
The background of the ListView is white, the foreground is black (they were set using the properties panel).