How do I edit data in a data table that is bound to a combo box without using a datagridview? - vb.net

I am using a combo box that is bound to a data table by the primary key. By selecting a value from the dropdown I am able to populate several textboxes in a form. I can easily add a new record to the data table. Occasionally I need to edit an existing record but I cannot discover the "index" of the row corresponding to the selection in the combo box even though I can populate the textboxes. Are there any methods to use with "datarow" to determine what record the "Pointer" is pointing to? If so perhaps then I could reference that datarow and write new data to the datatable, then update using a dataadapter... Any help would be greatly appreciated.

You're trying to solve a problem that doesn't exist. You don't need to know the index of the row or the row for that matter. What you should be doing is:
Binding your DataTable to a BindingSource, which you add in the designer.
Binding your BindingSource to your ComboBox AND your TextBoxes.
Select records in the ComboBox and edit in the TextBoxes as you like.
When it's time to save, call EndEdit on the BindingSource to ensure any pending edit is committed to the DataTable.
Use the same data adapter to save the changes from your DataTable as you used to populate it in the first place.
The binding would look something like this:
myDataAdapter.Fill(myDataTable)
myBindingSource.DataSource = myDataTable
With myComboBox
.DisplayMember = "DisplayColumn"
.ValueMember = "PKColumn"
.DataSource = myBindingSource
End With
myTextBox.DataBindings.Add("Text", myBindingSource, "EditColumn")
The saving would look something like this:
myBindingSource.EndEdit()
myDataAdapter.Update(myDataTable)
At no point do you have to care what rows were edited and where they are in the DataTable because Update will just save all changes.

Related

Changes in DataTable not seen from another form

I have a DataTable in my DataSet which is not bound to any table in the SQL Database since I need it only inside 2 forms. When I update it in Form1, it works just fine, the table is populated and I can see the data inside a DataGridView (here is the code I use for updating it):
Dim newProcesRow As DataRow = Me.SampleDataSet.Tables("TableSample").NewRow()
newProcesRow("Col1") = val1.ToString()
newProcesRow("Col2") = val2.ToString()
newProcesRow("Col3") = val3.ToString()
Me.Sample_DataSet.Tables("TableSample").Rows.Add(newProcesRow)
After doing this, the DataGridView in Form1 shows the entire table with no problems. After the user clicks a button, Form2 is shown, where there is a DataGridView as well with the same DataSource as the grid in the first form, the unbound table from the DataSet. I also tryed putting a MessageBox in Form2 to return the number of rows from the DataTable and the result was 0.
Is there any way I could make Form2 see the rows in the DataTable without binding it to the database? (I don't want to do unnecessary changes to the DataBase...) Or are there any saves/changes/updates I am not doing to the DataTable?
If there is anything else I should mention in order to make it easier to find a solution, tell me and I will add. Thanks in advance for any piece of advice, have a nice day! (:

Updating DataSource for DataGridView when DataSource set in properties

I have a DataGridView and have set the DataSource (dataset DsAll) and columns in the DataGridView properties.
Now i want to update the source/dataset. That is, I want to be able to limit or expand the data records shown in the grid, by putting a value in a TextBox and searching for only those records where that value is in a particular field (for instance employee id or department number, etc...)
I got this to work when I manually set the DataSource/bindings but I'am having issues when using the properties to set the DataSource.
Any help appreciated.
To elaborate on my comment, I suggest adding a BindingSource in the designer and then binding something like this:
myDataAdapter.Fill(myDataTable)
myBindingSource.DataSource = myDataTable
myDataGridView.DataSource = myBindingSource
and then filtering something like this:
myBindingSource.Filter = String.Format("MyColumn LIKE '%{0}%'", myTextBox.Text)

Datagridview should not clear on datasource = nothing

I am loading my datagridview through databinding. After that I would want to allow the user to add more rows to the datagridview.
This is only possible if I make the datasource of the datagridview to nothing.
When I do that , the datagridview clears when I say rows.add command.
How can I add a new row without clearing the data?
If you are using a Data-Bound DataGridView control, you cannot just simply add new row by using the cell property of the control.
A DataGridView that is bound using a DataSet can be access only using the DataSet properties. Forcing it to use the cell property can cause an error "Rows cannot be programmatically added to the DataGridView's rows collection when the control is data-bound."
Adding new row to a DataGridView control programmatically is useful when you want to pull some data from another table to a Bound DataSet with another table.
These links may help you :
http://social.msdn.microsoft.com/Forums/windows/en-US/c291d580-5a52-422a-b798-fbfb5f799b6a/cannot-add-new-rows-to-a-databound-datagridview-programmatically
http://www.codeproject.com/Questions/411452/Add-Rows-To-Databound-DatagridView

How to keep the data after removing the datasouce from a datagridview in vb.net?

I am populating a DataGridView (grid1) either by DataTable or DataSet.
I can remove a set of selected rows then add them to another unbound DataGridView (grid2).
The problem arises when I take a row from grid2 then add it to grid1.
Rows cannot be programmatically added to the DataGridView's rows
collection when the control is data-bound.
This occurs because
grid1.DataSource = myDataTable
or
grid1.DataSource = myDataSet
but when I do
grid1.DataSource = Nothing
all the rows from grid1 is removed.
Is there anyway to detach a datagridview from its datasource but keep the rows?
I can think of a solution wherein I would add another unbound DataGridView (grid3),
copy the content of the bound datagridview (grid1) to grid3 programmatically
then manipulate it from there.
I haven't tried this, but have a look at the Copy method:
grid1.DataSource = myDataTable.Copy
The MSDN says "Copies both the structure and data for this DataTable."
It may be that copying it also un-binds it.
If you have a databound grid, you should probably not be playing with the rows in the grid at all. Alter the table that you set as the datasource, then the grid will reflect the new rows.
dim row as datarow = myDataTable.newrow()
row.item("Column1") = "new value"
myDataTable.rows.add(row)
now the new row will show up on the databound grid. You can remove rows from the grid by removing it from the datasource datatable as well.

Can I page through grouped data in DataGridView?

I have a simple VB.NET 2008 app that helps users to edit fields in the database. Simple enough as a first "real" project in .NET, right?
For one table, I am currently using a DataGridView so it can be edited straight up. However, instead of offering the user the entire table, I'd like to group the data by the 'CompanyNumber' column and use a navigator to page through. In other words, I'd like the DataGridView to show me all the lines related to one company, then click the "next" arrow to show the next company, etc.
(I know I could do this with Xceed DataGrid, but I'm using Windows Forms not WPF, and I'd really prefer to do this with "pure" ADO.NET for this project.)
Update 2009-09-28:
So I have created a ComboBox filled from the same BindingSource, and configured its SelectedIndexChanged to change the Filter value on the DataGridView.
But still, filling the ComboBox--which should be easy!--continues to be a problem. I can either:
(a) fill it from the BindingSource, in which case I see multiples of each 'CompanyNumber' and I can't figure out a way to show only distinct values, or
(b) create another TableAdapter in the data source which is just a "Select DISTINCT CompanyNumber..." query, which mostly works, except that that first value of the list changes when I change the selection (e.g. if the ComboBox shows "100, 101, 102, 103" and I pick "102", then the list will show as "102, 101, 102, 103").
Any recommendations?
(Also, bonus if you can suggest how to make the BindingNavigator's arrows page through the 'CompanyNumber' filters instead of the items in the DataGridView... which is what I'd really like to see.)
What you could do is just force the DataGridView to sort CompanyName, this way all rows with the same company name are next to each other and the user can navigate the data grids with the paging that comes with it.
Alternatly, you could follow through with your combobox/DropDownList idea, which would be best. From what I understand when you select an item in the combobox everything in it changes?
Another way is to create two separate buttons, "Previous" "Next", that when clicked, will change the DataGridView's binding source to only show a certain company. You would need to store an array of company names, then store what the current DataGridView's binding source is displaying.
I ended up figuring it out myself, and the solution is clean and simple. Here are the basic steps:
create a DataView off of the table out of the DataSet
use the DataView.ToTable() method to create a new table filtered to only distinct values from the needed column ('CompanyNumber')
create a BindingSource which uses the new DataTable as its DataSource
bind the ComboBox to the new BindingSource
bind the BindingNavigator to the new BindingSource
Because the ComboBox and the BindingNavigator use the same BindingSource, they will update each other with the changes automagically.
Here's the rough code:
Private Sub CoNumsComboxBox_LoadData()
Dim dvCoNums As DataView, dtCoNums As DataTable
dvCoNums = New DataView(Me.ODBCDataSet.Tables("CompanyFundProfile"))
dvCoNums.Sort = "CompanyNumber ASC, FundNumber ASC"
dtCoNums = dvCoNums.ToTable("CompanyFundProfile", True, "CompanyNumber")
CoNums_BindingSource.DataSource = dtCoNums
CoNumsComboBox.DataSource = CoNums_BindingSource
CoNumsComboBox.DisplayMember = "CompanyNumber"
CoNumsComboBox.ValueMember = "CompanyNumber"
'attach handler which changes DataGridView1's filter when this changes
AddHandler ToolStripComboBox1.SelectedIndexChanged, AddressOf CoNumsComboBox_SelectedIndexChanged
CompanyFundProfile_BindingNavigator.BindingSource = CoNums_BindingSource
End Sub