Problem with datagridview and AddNew - vb.net

I've created a VB 2008 program to track work requests. It all works perfectly on a VISTA box, but I am having an issue with the program on an XP environment with adding new records.
Basically I've got 2 tabs: TAB 1 holds a datagridview with limited info and a calendar. Selecting dates on the calendar change the info in the datagridview. TAB 2 holds all the available info for that record in text/combo boxes. Both the datagridview and text boxes use the same Binding Source, so they are always in sync whenever the user selects a row from the datagridview. When you select the NEW button, TAB 2 appears with all the text boxes empty so the user can add data. If you look back on TAB 1, you see an empty, new row added to the datagridview (user can not directly add a row in the datagridview as AllowUserToAdd is set to false). If you let the app stay in the AddNew record state on VISTA, you remain on that new record until you select SAVE or CANCEL. On XP, however, after 1 minute time lapse, all the empty fields will eventually fill in with an existing record for that particular calendar day. When you look back on TAB 1, you no longer see the new empty row, you only see existing records previously saved.
Any ideas on how to resolve?? Thanks for any assistance.
Here is the code for adding new records:
Private Sub cmdNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdNew.Click
'Focus on Work tab
TabControl1.SelectedTab = tabWork
'Change the files from read-only
bEditMode = True
ChangeEditMode()
'Clear the current information stored in the fields
Try
Me.BindingContext(WorkRequestBindingSource).AddNew()
Catch ex As Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
End Try
'Hidden text boxes populate with current selected calendar
'Used to populate TimeIn and DateNeed because if never clicked on, will populate as NULL on save
dtpDateNeed.Text = txtDate.Text
dtpTimeIn.Text = txtTime.Text
End Sub

This is definitely an environmental issue. To solve the problem I would need to know which browsers you are using on each machine and some of the settings on each.
It sounds like the XP machine is refreshing the page after a timeout period and therefore munging the new record. I have seen that happen before and it stinks.
You might need to consider saving some more state information in the viewstate to catch that kind of thing.

If the code is exactly the same I wonder if it is an environment issue e.g. something like different international options or version of framework?

Related

RDLC report for multiple checked box items in Listview in vb.net

I need a little help here.
I have a form which shows all the clients, stored in the access database, as a check-box items in a listview control. I want a user to check multiple checkboxes to view details of the selected clients and show it in the rdlc report.
I have written the following codes in VB.net at form_load event, but it only shows the last selected item.
I want some seggustion for the codes which shows details in the rdlc report for all the selected clients.
Private Sub TodaysPendingCompliances_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each SelctedCLient As ListViewItem In TodaysCompliances.ListView1.CheckedItems
Me.NoticeComplianceTableAdapter.FillByClientANDComplianceDate(Me.ComplianceDBDataSet.NoticeCompliance, SelctedCLient.Text)
Next
Me.ReportViewer1.RefreshReport()
End Sub
You help will be highly appreciated.
I beleive your problem is that NoticeComplianceTableAdapter.FillByClientANDComplianceDate overwrites the existing data with fresh data from the current iteration every time it is called, so it only holds the last iteration data.
To fix that you will either need to modify that function (or create an overload for it) to not clear the existing data, or create a temporary container that you declare before the loop, and add new data to each time, then attach the report to that temporary data.
Thank you Mr. Bradlet Uffner for you response. You reply helped in finding the solution.
The solution is to set the Clearbeforefill = False for the NoticeComplianceTableAdater
Setting Clearbeforefill to false does not clear the existing data with fresh data from the current iteration.

VB.NET web application - Update a data bound Listbox when underlying table / query changes

I have a page in my web application that contains two listboxes with buttons to move items back & forth between them. Each listbox is bound to a SQL query, the results of which change as the selected items are added or removed from the corresponding lists. This all works fine, except I cannot get the list boxes to update their contents on the fly, however if I refresh the web page, the contents update correctly.
Basically the user selects items in LeftListbox and clicks the Add button which calls code to loop through the LeftListbox and for each selected item adds a new record to a table (Score). The RightListbox should then update to show that the items have been added to the table.
Here is a snippet of code from the Click event of the Add button:
Dim i As Integer
For i = 0 To (LeftListbox.Items.Count() - 1)
If LeftListbox.Items(i).Selected Then
Try
DbUtils.StartTransaction()
Dim rec As ScoreRecord = New ScoreRecord
rec.Player_ID = CInt(Me.LeftListbox.Items(i).Value)
rec.Save()
DbUtils.CommitTransaction()
Catch ex As Exception
DbUtils.RollBackTransaction()
Me.Page.ErrorOnPage = True
Finally
DbUtils.EndTransaction()
End Try
End If
Next i
'** Here is where I want to refresh the list **
I've searched quite a bit for a solution, but I can't find anything that works so any help would be much appreciated.
Andrew
Use the same method (or code) used to populate the "right listbox" in the first place. The right ListBox's DataSource will be the same as it was prior to this code snipped being ran, so it must be updated since the underlying data has changed.

How to set default values for data bound controls for addition in VB.NET

I have a vb.net 2010 form with 22 data bound controls from two tables held in a dataset which is navigated by a bindingnavigator. This successfully adds deletes and updates. However what I need is when adding a new record I need some of the fields to be pre filled out. More specifically I have points balance fields etc which could be any value but will normally be 0 on a new customer so I want to initialise them to 0 when adding new records.
I located an AddingNew event on my datasource but this is called before the new item is added and thus all my initialisation is lost.
any help on this would be appreciated.
kind regards
Feldoh
Since you are using DataTables, you can manually set the DefaultValue property of the DataColumn:
Dim dt As New DataTable
Dim dc As New DataColumn("test", GetType(String))
dc.DefaultValue = "hello"
dt.Columns.Add(dc)
dt.Rows.Add()
Debug.WriteLine(dt.Rows(0)("test").ToString)
Result: hello
Answer including multiple linked tables solution:
Like LarsTech said using
dataset.table.Columns.Item("someField").DefaultValue = someValue
works nicely if you have a standard default but it also works for generated defaults, if you reset this default on saving to the next value you want if a new addition is made. However if you are using a dataset as your data source where a child table record cannot feasibly be generated (like in my case where an account id will be generated only on saving using a database trigger to link all different kinds of accounts) you can still set defaults for the other fields, the ones from the sibling (or non-existent parent) table but
dataset.siblingTable.Columns.Item("someField").DefaultValue = someValue
WILL NOT WORK as the binding navigator only generates the first sibling and the parent is not generated until the trigger. However on the BindingSource.PositionChanged event of the binding source that IS generated by clicking add you can freely put defaults into the actual controls on the screen and they will not be overwritten by nulls, clearly you need to restrict this so it only happens if the user pressed add by adding a variable to the Clicked event of the add button to tell you when add has been clicked and resetting this variable on save or roll-back. It is also possible to modify the bindings themselves which have an if null or empty default value.
Hope this helps someone else :)
Use the MouseUp event on the 'Add Row' button in the BindingNavigator instead of the "Click" event. This is becouse the new ROW does not exist in the datagridview until AFTER the click event is completed.
Private Sub BindingNavigatorAddNewItem_MouseUp(sender As Object, e As MouseEventArgs) Handles BindingNavigatorAddNewItem.MouseUp
'works with add row from the binding navigator
myDataGridView.Item(3, myDataGridView.CurrentRow.Index).Value = txtDefaultDescrip.Text.Trim
End Sub
to do this same thing when adding data directly in you DataGridView do this.
Private Sub myDataGridView_DefaultValuesNeeded(sender As Object, e As DataGridViewRowEventArgs) Handles myDataGridView.DefaultValuesNeeded
'works with add row inside a datagridview
e.Row.Cells(3).Value = txtDefaultDescrip.Text.Trim
End Sub
In this example I have a editable default value shown on my from. If you have a non-changing default value (e.g., is always 1 for column 3) then you should do that when setting up your datasource.

Updating a control on another form with the results of a dialog box

I made a windows form which contains a listbox (named VenueList). The listbox is pulling it's values from a list provided by a binding source VenuesBindingSource which is pulling in a ID for the value and a name for the text.
There is a button which is causing a DialogBox to appear which is asking for values to store in the database for a NEW venue. Once the values are filled and insert the database, what's supposed to happen is that the dialog box closes and goes back to the original form which invoked it.
However, instead of updating the list. The list stays the same. But if you close the form and reopen it, you see that a new value was added.
TournamentSettings.VenuesTableAdapter.InsertVenueQuery(Trim(VenueNameTxt.Text), Trim(VenueAddress1Txt.Text), Trim(VenueAddress2Txt.Text), Trim(VenueCityTxt.Text), Trim(VenueProvinceTxt.Text), Trim(VenueZipTxt.Text), Trim(CountryBox.SelectedValue), Trim(VenuePhoneNo.Text), VenueType.SelectedText, VenueWebAddress)
TournamentSettings.VenuesTableAdapter.Fill(TournamentSettings.VenueNameList.Venues)
In the above code, InsertVenueQuery is the name of a query from the designer which is invoked to add the values onto the tableadapter VenuesTableAdapter which is used to fill the combo box on load. I also sent the Fill command to refill the table with the new value.
So the question is, should I go about doing this another way, rather than feeding the Table adapter and sending a fill command on to the datatable? Or is there something that I'm not doing here which I should to force that value into the list. I'm tempted to redo everything outside of the designer but that's a lot of code since I have to essentially run two commands (one to insert the data, and another to get the ##IDENTITY value since this is run on an access database.)
Okay. This one I had to think about for a moment.
Instead of me creating a block of done on the load event, I instead created a sub function called "FillVenueList".
I used the following block of code:
Public Sub FillVenueList()
' Adding values from database to a datatable.
' From there will add to the list box.
Dim VenueConnection As New OleDb.OleDbConnection(DBconnection)
VenueConnection.Open()
Dim VenueConnectionQuery As New OleDb.OleDbCommand("SELECT VenueID, VenueName FROM Venues", VenueConnection)
Dim VenueDataAdapter As New OleDb.OleDbDataAdapter(VenueConnectionQuery)
Dim VenueDataSet As New DataSet
VenueDataAdapter.Fill(VenueDataSet, "Venues")
TrnVenueLst.DataSource = VenueDataSet.Tables("Venues")
TrnVenueLst.DisplayMember = "VenueName"
TrnVenueLst.ValueMember = "VenueID"
VenueConnection.Close()
End Sub
From there I called THIS sub on both the form AND the Add Venue window and I can safely see that this works. SO THAT is how you get a new value onto the form, don't use it as a part of the Load Event but rather call it from the load event block, then call it when you want to add to the list.

Updating a Database from DataBound Controls

I'm currently creating a WinForm in VB.NET bound to an access database.
Basically what i have are two forms: one is a search form used to search the database, and the other is a details form. You run a search on the searchForm and it returns a list of Primary Keys and a few other identifying values. You then double click on the entry you want to view, and it loads the details form.
The Details form has a collection of databound controls to display the data: mostly text boxes and checkboxs. The way i've set it up is i used the UI to build the form and then set the DataBindings Property of each control to "TblPropertiesBindingSource - " where value name is one of the values in the table (such as PropertyID or HasWoodFloor).
Then, when you double click an entry in the searchform, I handle the event by parsing the Primary Key (PropertyID) out of the selected row and then storing this to the details form:
Note: Detail is the details form that is opened to display the info
Private Sub propView_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles propView.CellDoubleClick
Dim detail As frmPropertiesDetail = New frmPropertiesDetail
detail.id = propView.Rows(e.RowIndex).Cells(0).Value
detail.Show()
End Sub
Then, upon loading the details form, it set's the filter on the BindSource as such:
TblPropertiesBindingSource.Filter() = "PropertyID=" & id
This works great so far. All the controls on the details form will display the correct info. The problem is updating changes.
Scenario:
If i have the user load the details for say, property 10001, it will show a description in a textBox named descriptionBox which is identical to the value of the description value of for that entry in the database. I want the user to then be able to change the text of the text box (which they can currently do) and click the save button (saveBut) and have the form update all the values in the controls to the database.
Theorectically, it should do this as the controls are DataBound, thus i can avoid writing code that tells each entry in the database row to take the value of the aligned control.
I've tried calleding PropertiesTableAdapter.Update(PropertiesBindingSource.DataSource), but that doesnt seem to do it.
Ok, I was able to figure this out picking apart some code I pillaged from a friend.
Everything was ok, the problem was the updating
When I was saving the data, i was calling just:
Me.TblProptertiesTableAdapter.Update(Me.TblPropertiesBindingSource.DataSource)
The correct code, without changing anything else is:
Me.Validate()
Me.TblPropertiesBindingSource.EndEdit()
Me.TblPropertiesTableAdapter.Update(Me.RentalPropertiesDataSet.tblProperties)
Me.RentalPropertiesDataSet.AcceptChanges()
Where RentalPropertiesDataSet is the database where TblProperties comes from. Inorder for this to work, make sure TblPropertiesBindingSource.DataSource is RentalPropertiesDataSet.Properties This was autosetup for me by VS08 when it created the BindingSource.
Basically, I needed to tell teh BindingSource to stop allowing the fields to be edited. Then we save the changes to the database, and lastly we tell the DataBase to accept the changes.