UltraWinGrid Auto Refresh - vb.net

In my vb.net project, I have 3 forms. home_mdi, Viewfrm and AddDatafrm.
Viewfrm has an UltraWinGrid on it, which is displaying some data. When I click the add data button, AddDatafrm opens. When data is saved, the form then closes.
At this point, I want the UltraWinGrid on Viewfrm to update/refresh and display the data that I added. At the moment, it doesn't display it until I close Viewfrm and then open it again.
The images show this. (Data is not there at the start, it then gets added and does not appear. The final image is the form displaying the new data, after I've re-opened it.
How do I change this?
Current code:
To open the Add form
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
Using fp = New frmAddData(Globals.m_database)
If fp.ShowDialog() = DialogResult.OK Then
ugData.DataSource = Nothing
getPeople()
End If
End Using
End Sub
To save the entered information (on the Add form)
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
Dim m_cn As New OleDbConnection
m_cn = Globals.m_database.getConnection()
If txtFirstName.Text = "" Then
MsgBox("First name cannot be blank")
ElseIf txtLastName.Text = "" Then
MsgBox("Last name cannot be blank")
ElseIf txtAge.Text = "" Then
MsgBox("Age cannot be blank")
ElseIf txtPostCode.Text = "" Then
MsgBox("Postcode cannot be blank")
Else
Dim personID As Integer = database.SaveNewPerson(txtFirstName.Text, txtLastName.Text, txtAge.Text, txtPostCode.Text, m_cn)
MsgBox("Save successful")
txtFirstName.Text = ""
txtLastName.Text = ""
txtAge.Text = ""
txtPostCode.Text = ""
Globals.savedValue = True
Me.Close()
End If
End Sub
Call to load the database on the View form:
Public Sub getPeople()
Try
Dim sql As String = "SELECT * FROM tblPerson ORDER BY [personID] ASC;"
Dim cm As New OleDbCommand(sql, Globals.m_database.getConnection())
Dim da As New OleDbDataAdapter(cm)
Dim dt As New DataTable()
da.Fill(dt)
ugData.DataSource = dt
Catch Ex As Exception
mdi1.errorLog(Ex.Message, Ex.StackTrace)
MsgBox("Failed to retrieve data, refer to error log")
End Try
End Sub

In a WinForm app, a modal dialog is closed automatically by the engine if a button is pressed and its DialogResult property is set to anything but None. Then the Winform engine sets the form DialogResult to the same property of the button, exits from the ShowDialog call and returns the DialogResult property of the button clicked.
Usually this is more than enough to handle situations like yours above. (Or, in general situations where a user choose between Yes/No or OK/Cancel scenarios)
In your code (as explained in chat) you have the DialogResult property of the Save button set to DialogResult.None. This, means that the Winforms engine doesn't close automatically your form and you need to write your own closing routine.
But, if you forget to set the Form property DialogResult to DialogResult.OK, your calling code will never be able to refresh the grid because the test for DialogResult.OK fails.
So, whatever closing code you have to close the fromAddData instance, remember to set the form DialogResult property with
Me.DialogResult = DialogResult.OK
or, if something is gone wrong, with
Me.DialogResult = DialogResult.Cancel

Related

How can i use multiple buttons on one clickEvent and acces all of them

i'm new here and I do VB.net programming.
I want to do something very specific but i don't know how to aproach it. I have one ClickEvent that i want to use for various Buttons. The problem is that i want to make that each button changes one TextBox. I don't want to do this in 4 separate ClickEvents because i would be repeating a lot of code.
Here is what i want to do:
Private Sub btnOpenDial1_Click(sender As Object, e As EventArgs) Handles btnOpenDial1.Click, btnOpenDial2.Click, btnOpenDial3.Click, btnOpenDial4.Click
Dim UnitLetter As String = Environment.CurrentDirectory.Substring(0, 3)
SaveFileDialog1.InitialDirectory = UnitLetter
SaveFileDialog1.Filter = "rtf file (*.rtf)|*.rtf"
If SaveFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
'name is a TextBox variable that i have at the top of the program
name = SaveFileDialog1.FileName
If (name IsNot Nothing) Then
' I press btnOpenDial1, this textbox changes
txtDoc1.Text = nombre
' I press btnOpenDial2, this textbox changes
txtDoc2.Text = nombre
' I press btnOpenDial3, this textbox changes
txtDoc3.Text = nombre
' I press btnOpenDial4, this textbox changes
txtDoc4.Text = nombre
End If
Catch Ex As Exception
MessageBox.Show("No se ha podido grabar el archivo: " & Ex.Message)
End Try
End If
End Sub
I hope i explained good enough. English is not my main language. I just don't want to repeat more code on my program. Thanks in advance
You can use something like this:
You can use one ClickEventHandler Method for all buttons (better of the same type as EventArgs may be different for different types).
On click Event of each button you can detect it from its name (as code shows). At this point, when you have detected the button that is clicked you can run specific code in relation with that button.
Hope was what you wanted.
Private Sub btnOpenDial1_Click(sender As Object, e As EventArgs) Handles btnOpenDial1.Click,
btnOpenDial2.Click,
btnOpenDial3.Click,
btnOpenDial4.Click
Dim pressedButton As Control = CType(sender, Control)
Dim UnitLetter As String = Environment.CurrentDirectory.Substring(0, 3)
SaveFileDialog1.InitialDirectory = UnitLetter
SaveFileDialog1.Filter = "rtf file (*.rtf)|*.rtf"
If SaveFileDialog1.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
Try
'name is a TextBox variable that i have at the top of the program
Name = SaveFileDialog1.FileName
If (Name IsNot Nothing) Then
Select Case pressedButton.Name
Case "btnOpenDial1" : txtDoc1.Text = nombre
Case "btnOpenDial2" : txtDoc2.Text = nombre
Case "btnOpenDial3" : txtDoc3.Text = nombre
Case "btnOpenDial4" : txtDoc4.Text = nombre
End Select
End If
Catch Ex As Exception
MessageBox.Show("No se ha podido grabar el archivo: " & Ex.Message)
End Try
End If
End Sub

VB.net: Can't run a public sub in another form

I have a Main (MDIParent) and Ticket (MDIChild). In Ticket form, there is a listview that displays the previous ticket trouble, pending and open ticket. When I add a new ticket trouble, there is a button BtnCreat_T, it will appear the TicketAdd form. The Ticket form will not close and I use the showdialog() for TicketAdd to show. When I add the new ticket trouble in TicketAdd form, the listview in Ticket form will not refresh, update, or reload.
Also, I noticed that in TicketAdd form I can't run the Public Sub ViewRecords created in Ticket form.
So here is my code in Ticket form Public Sub ViewRecords. I call this in Ticket form load:
Public Sub ViewRecords()
Dim i As Integer = 0
LvTicket.Items.Clear()
con.Open()
SQLString = String.Empty
SQLString = "SELECT * FROM TblTickets ORDER BY Ticket_ID DESC"
SQLDA = New SqlDataAdapter(SQLString, con)
Using SQLDT As New DataTable
SQLDA.Fill(SQLDT)
Do Until i = SQLDT.Rows.Count
With LvTicket
.Items.Add(SQLDT.Rows(i)("Ticket_ID"))
With .Items(.Items.Count - 1).SubItems
.Add(SQLDT.Rows(i)("Dept"))
.Add(SQLDT.Rows(i)("Aff_Per"))
.Add(SQLDT.Rows(i)("N_Prob"))
.Add(SQLDT.Rows(i)("Prob_Des"))
.Add(SQLDT.Rows(i)("DateTime"))
.Add(SQLDT.Rows(i)("Findings"))
.Add(SQLDT.Rows(i)("Status"))
End With
i += 1
End With
Loop
End Using
con.Close()
End Sub
And this is my code for adding the new trouble ticket in TicketAdd form BtnCreat_T button:
Private Sub BtnCreateT_Click(sender As Object, e As EventArgs) Handles BtnCreateT.Click
If CmbDept.Text = "" Or TxtAffectedP.Text = "" Or CmbNOProblem.Text = "" Or TxtProbD.Text = "" Or TxtFindings.Text = "" Or CmbStatus.Text = "" Then
MsgBox("Their is an empty field, please check!", MsgBoxStyle.Exclamation, "Ticket Details")
Else
If MsgBox("Are all fields are correct? Please double check!", MsgBoxStyle.Information + MsgBoxStyle.YesNo, "Ticket Details") = MsgBoxResult.Yes Then
GetTicket()
con.Open()
SQLString = String.Empty
SQLString = "INSERT INTO TblTickets (Ticket_ID, Dept, Aff_Per, N_Prob, Prob_Des, DateTime, Findings, Status)" &
"VALUES (#TID, #D, #AP, #NP, #PD, #DT, #F, #S)"
SQLCmd = New SqlCommand(SQLString, con)
SQLCmd.Parameters.AddWithValue("#TID", LblTicketID.Text)
SQLCmd.Parameters.AddWithValue("#D", CmbDept.Text)
SQLCmd.Parameters.AddWithValue("#AP", TxtAffectedP.Text)
SQLCmd.Parameters.AddWithValue("#NP", CmbNOProblem.Text)
SQLCmd.Parameters.AddWithValue("#PD", TxtProbD.Text)
SQLCmd.Parameters.AddWithValue("#DT", DTPicker.Value)
SQLCmd.Parameters.AddWithValue("#F", TxtFindings.Text)
SQLCmd.Parameters.AddWithValue("#S", CmbStatus.Text)
SQLCmd.ExecuteNonQuery()
MsgBox("Data has been saved! Your Ticket Number is: " & LblTicketID.Text, MsgBoxStyle.OkOnly, "Ticket Details")
con.Close()
EmptyField()
CmbDept.Select()
Ticket.ViewRecords()
Else
CmbDept.Select()
End If
End If
End Sub
After I click the BtnCreat_T button, the TicketAdd form will not close and the listview in Ticket form must be updated or refresh.
There is no error when running this code but I can't reload or update the listview in Ticket form.
As you mentioned you show the TicketAdd Form modal (.ShowDialog())
So I would suggest as long this TicketAdd from is showing, it's not realy relevant to update the Ticket form, because your application focus is clampt on your ticketAdd-Dialog.
After you close your TicketAdd form you can call ViewRecords from within the sub where you showed your TicketAdd form. There you have direct access to your true Instance of Ticketform (mentioned by #JayV)
But if you realy have to update every record as it gets saved you can handle it with an action you pass to your TicketAdd form
In your Ticketform where you show your TicketAdd, set the Action (Reference to the Sub Signature of Ticketform)
Dim lTicketAdd As New TicketAdd
lTicketAdd.SetUpdateData(AddressOf ViewRecords)
lTicketAdd.ShowDialog()
Extend your TicketAdd form with a Sub to asign the Action-Reference and where you save your DataRecord call this Action
'And Action to hold the Reference to your ViewRecords Code from the parent Form
Private _RefreshData As Action
'A sub to set this Action Reference
Public Sub SetUpdateData(ByVal vDelegation As Action)
_RefreshData = vDelegation
End Sub
Private Sub BtnCreateT_Click(sender As Object, e As EventArgs) Handles BtnCreateT.Click
.....
'Your code from above
'Instead of calling ViewRecord, call the Action
If _RefreshData IsNot Nothing Then
_RefreshData.Invoke()
End If
End Sub

Update From DataGridView to Database

Dim sb As New MySqlConnectionStringBuilder
sb.Server = Form1.hostname.Text
sb.UserID = Form1.rootuser.Text
sb.Password = Form1.rootpassword.Text
sb.Database = Form1.hostdb.Text
sb.Port = Form1.hostport.Text
Using connection As New MySqlConnection(sb.ConnectionString)
Try
connection.Open()
Dim adapter1 As New MySqlDataAdapter(TextBox1.Text, connection)
Dim cmdb1 = New MySqlCommandBuilder(adapter1)
Dim ds As New DataSet
Dim words As String() = TextBox1.Text.Split(New Char() {" "c})
Dim tablenamewords = (words(3))
adapter1.Update(ds, tablenamewords)
Catch ex As MySqlException
MessageBox.Show(ex.Message)
Finally
connection.Dispose()
End Try
End Using
It's giving me this error:
Update unable to find TableMapping['creature_template'] or DataTable 'creature_template'.
I want to select items then use a DataGrid to update them.
Note: tablenamewords = "creature_template"
You can solve this in alot of different methods.
I prefer to update the DB with a single query every time the the user ends editing a cell.
BUT FIRST you have to bind a source to your DataGridView!
How to bind a source:
Go to your application design an click on your DataGridView
Click on the pause/start like little button as shown:
Click on the "ComboBox" like textbox labeled as "chose data source" as shown and click on it:
It will open a "form", click on the Add data source as shown:
Follow the wizard, you can do it without any furhter explanation!
Well done, you almost completed it. Just go in your code, and look for this sub:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.your_table_nameTableAdapter.Fill(Me.your_db_nameDataSet.your_table_name)
End Sub
The line inside your Form1_Load Sub will upload the data inside your DataGridView, leave it there if you want it to load with the form or cut/paste it wherever you like.
Now you can add this the code to programmatically update the DB:
Private Sub DataGridView1_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit
Try
Dim location As Point = DataGridView1.CurrentCellAddress
Dim sqlCmd As String = "UPDATE table_name SET " & _
DataGridView1.Columns(location.X).Name.Replace("DataGridViewTextBoxColumn", "") & " = #Data " & _
"WHERE " & _
DataGridView1.Columns(0).Name.Replace("DataGridViewTextBoxColumn", "") & " = #ID"
Using myConn As New SqlConnection(My.Settings.VISURE_DA_PDFConnectionString)
myConn.Open()
Using myCmd As New SqlCommand(sqlCmd, myConn)
myCmd.Parameters.Add("#Data", SqlDbType.VarChar)
myCmd.Parameters.Add("#ID", SqlDbType.Int)
myCmd.Parameters("#Data").Value = DataGridView1.Rows(location.Y).Cells(location.X).Value
myCmd.Parameters("#ID").Value = DataGridView1.Rows(0).Cells(location.X).Value
myCmd.ExecuteNonQuery()
End Using
myConn.Close()
End Using
Catch ex As Exception
Err.Clear()
End Try
End Sub
Remarks:
location.X is the col index, location.Y is the row index
DataGridView1.Columns(0).Name This is my ID (primary key) and it is always in the first column. Change it with yours.
Don't forget to add .Replace("DataGridViewTextBoxColumn", "") whan you are getting your column name
As previously said, this code will update your DB every time the user edits one cell on your DataGridView updating only the edited cell. This is not a big issue because if you want to edit two ore more cell, every time you leave an edited cell the method DataGridView1_CellEndEdit is fired!

Send value to parent then close child form, on event

I have a parent form with a combobox populated from a database, from which the user can select. The last value in the combo box is "add new", if the user selects this, a child form opens for the user to add a new value to the database. I have a button press event to add this value to the database, send the new return value to the parent and close the form. The parent should then select the new value from it's combo box and wait for the user to perform another action.
However, the code to send the return value to parent and close the form isn't working correctly. I hide the child, then call a function on it with the parent to access the return value. At this point the child form shows and the code stops before it runs another hide or close.
How can I fix this (code below)?
Parent Combobox event:
Private Sub cmbLocations_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbLocations.SelectedIndexChanged
If Not cmbLocations.SelectedIndex = -1 Then
If cmbLocations.SelectedIndex = cmbLocations.Items.Count - 1 Then
If diaAddLocation.IsAccessible = False Then diaAddLocation.Activate()
diaAddLocation.RequestSender = Me
diaAddLocation.ShowDialog()
FillLocations()
cmbLocations.SelectedIndex = LocationFromLocationName(diaAddLocation.formresult)
diaAddLocation.Close()
diaAddLocation.Dispose()
Else
bttYes.Enabled = True
End If
End If
End Sub
Child Button Press and Return value function
Public Sub bttAddLOCtoDatabase_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttAddLOCtoDatabase.Click
Dim LocationToBeAdded As String
LocationToBeAdded = "'" & TextBox1.Text & "'"
AddLocation("'" & textbox1.Text & "'")
FormResult = textbox1.Text
GetLocations()
frmFieldMaster.InitialiseNewParameter()
Me.Hide()
End Sub
Public Function Result() As String
Return FormResult
End Function
EDIT:
code with Steve's solution implemented:
Public Sub bttAddLOCtoDatabase_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bttAddLOCtoDatabase.Click
Dim LocationToBeAdded As String
LocationToBeAdded = "'" & TextBox1.Text & "'"
AddLocation("'" & textbox1.Text & "'")
FormResult = textbox1.Text
GetLocations()
frmFieldMaster.InitialiseNewParameter()
DialogResult = Windows.Forms.DialogResult.OK
'me.Hide()
End Sub
Public Function Result() As String
Return FormResult
Me.Close()
End Function
Private Sub cmbLocations_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles cmbLocations.SelectedIndexChanged
Dim ValueTaken As Boolean = False
If Not cmbLocations.SelectedIndex = -1 Then
If cmbLocations.SelectedIndex = cmbLocations.Items.Count - 1 Then
Using diaaddlocation = New diaAddLocation
diaaddlocation.requestsender = Me
If DialogResult.OK = diaaddlocation.showdialog Then
FillLocations()
cmbLocations.SelectedIndex = LocationFromLocationName(diaaddlocation.result)
diaaddlocation.close()
ElseIf DialogResult.Cancel = diaaddlocation.showdialog Then
cmbLocations.SelectedIndex = -1
End If
End Using
Else
bttYes.Enabled = True
End If
End If
End Sub
When I run the code it enters IF DialogResult.OK... and opens the child. Then when I close the child the parent runs the next two lines of code and get the result from the child. After this the parent runs the line IF DialogResult.OK... again and stops with the child open. The code never reaches the diaaddlocation.close line.
You don't need all of this. You could try something like this
If cmbLocations.SelectedIndex = cmbLocations.Items.Count - 1 Then
Using diaAddLocation = new diaAddLocation()
diaAddLocation.RequestSender = Me
if DialogResult.OK = diaAddLocation.ShowDialog() then
FillLocations()
cmbLocations.SelectedIndex = LocationFromLocationName(diaAddLocation.formresult)
End If
End Using
Else
.....
This requires the DialogResult property for bttAddLOCtoDatabase set to DialogResult.OK and the child form AcceptButton property set to bttAddLOCtoDatabase. Now you could remove the Hide() call inside the bttAddLOCtoDatabase_Click method
This works because, until you don't exit the Using statement, your child form is still available to read its properties (results)
EDIT: Not related to the main problem, but these lines are wrong:
ElseIf DialogResult.Cancel = diaaddlocation.showdialog Then
cmbLocations.SelectedIndex = -1
you should go with
Using diaAddLocation = new diaAddLocation()
diaAddLocation.RequestSender = Me
Dim dr = diaAddLocation.ShowDialog()
if dr = DialogResult.OK then
....
else if dr = DialogResult.Cancel then
....
end if
I don’t understand what is issue but if you are not getting value of “FormResult”
It doesn’t matter if you close from but it will be better to set DialogResult before closing it, cause you are showing it as dialog (showdialog)
Verify that diaAddLocation is instance of you window not the window class directly
If name of you form is frmdiaAddLocation then do not use it like
frmdiaAddLocation.showdialog
use it like
Dim diaAddLocation AS frmdiaAddLocation = New frmdiaAddLocation()
diaAddLocation.ShowDialog()
only using like this way will provide you result value

Update Combobox on Save and Delete

I have a bound combo box with employee profile names. I have two buttons: save and delete buttons.
When I edit a selected profile, I hit save and automatically the change is reflected in the bound combo box, but when I hit delete or create new profile, I have to close the app and when I open it I see the changes in the bound combo box.
The combobox.Refresh() no work
This is my code:
Private Sub deleteselectedprofile_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_deleteprofile_oninsideprofiledittap1.Click
Dim mconn As New SqlConnection("Data Source=(local);Initial Catalog=epmapp_db;Integrated Security=true;")
Dim cmd As New SqlCommand
cmd.Connection = mconn
cmd.CommandType = CommandType.Text
cmd.CommandText = "delete GeneralInfo where RecordId= " + cbox_profiles.SelectedValue.ToString
Try
If MessageBox.Show("¿Está seguro de querer borrar este perfil?", _
"Delete", MessageBoxButtons.YesNo, _
MessageBoxIcon.Warning) = DialogResult.No Then
mconn.Close()
MsgBox("Operación Cancelada")
Else
mconn.Open()
cmd.ExecuteNonQuery()
MessageBox.Show("Su perfil se ha actualizado exitosamete")
Clear_Form_tap1()
disabling_controlstap1()
btn_newprofile_onload_tap1.Visible = True
btn_saveprofile_oninside_profileedit_tap1.Visible = False
btn_editprofile_oncboxselectiontap1.Visible = False
btn_cancelprofileedit_onprofileselectiontap1.Visible = False
btn_deleteprofile_oninsideprofiledittap1.Visible = False
cbox_profiles.Enabled = True
ErrorProvider1.Clear()
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
Finally
mconn.Close()
End Try
End Sub
I set my combo box in the Design Tab using the...
Combo Box Task
Use Data Bound Items
Data Binding Mode
Data Source = GeneralInfoBindingDource
Display Member = Nombre
Value Member = RecordId
Selected Value = none
My save button code...
Private Sub btn_saveprofile_oninside_profileedit_tap1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_saveprofile_oninside_profileedit_tap1.Click
Me.Validate()
Me.GeneralInfoBindingSource.EndEdit()
Me.GeneralInfoTableAdapter.Update(Me.Epmapp_dbDataSet)
Try
MessageBox.Show("Su perfil ha actualizado exitosamete")
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Clear_Form_tap1()
disabling_controlstap1()
btn_saveprofile_oninside_profileedit_tap1.Visible = False
btn_cancelprofileedit_onprofileselectiontap1.Visible = False
btn_deleteprofile_oninsideprofiledittap1.Visible = False
btn_editprofile_oncboxselectiontap1.Visible = False
btn_newprofile_onload_tap1.Visible = True
cbox_profiles.Enabled = True
ErrorProvider1.Clear()
End Sub
I have try a few codes but none works for me. Can any one help me with a code for this small issue?
If I followed this correctly, when you delete a record you are doing so directly in the database. However, you are not updating your datasource (GeneralInfoBindingDource). My guess is you have the same issue when you create a new item. The database is updated, so when it reloads the data from the database its correct. (When you reopen it).
You need to update your datasource.
Your save works because you are updating the datasource, rather than writing changes to the database without updating it.
Me.GeneralInfoBindingSource.EndEdit()
Me.GeneralInfoTableAdapter.Update(Me.Epmapp_dbDataSet)