Textbox not refreshing - vb.net

Dim VoucherOpenConnection As New OleDbConnection
' VoucherOpenConnection = New OleDbConnection
VoucherOpenConnection.ConnectionString = "My Connection String"
Dim VoucherString As String = "My Query"
Dim DAVoucherString As New OleDbDataAdapter(VoucherString, VoucherOpenConnection)
Dim DTVoucherString As New DataTable
DAVoucherString.Fill(DTVoucherString)
If DTVoucherString.Rows.Count <> 0 Then
cmbCategory.Text = DTVoucherString.Rows(0).Item(8).ToString
txtDetails.Text = DTVoucherString.Rows(0).Item(2).ToString
txtshop.Text = DTVoucherString.Rows(0).Item(3).ToString
txtAmount.Text = DTVoucherString.Rows(0).Item(4).ToString
txtRemarks.Text = DTVoucherString.Rows(0).Item(5).ToString
txtInvoiceNum.Text = DTVoucherString.Rows(0).Item(11).ToString
txtCashAmt.Text = DTVoucherString.Rows(0).Item(6).ToString
Me.Refresh()
Else
MsgBox("No valid record could be found(Cash)!!")
End If
I have the above code inside a sub procedure and call it from another form. When the sub is called the first time, all the textboxes display the correct values. But when I try again, the values do not update. Putting a breakpoint in the sub reveals that the code is working correctly as hovering the mouse over the textboxes shows the correct values.
I have already tried the following methods to no avail:
Me.Refresh
Me.Update
Textbox.update/refresh
This is in VB.NET 2019.
Edit:Code in the calling form:
Private Sub DGVTotalReport_CellMouseDoubleClick(sender As Object, e As
DataGridViewCellMouseEventArgs) Handles
DGVTotalReport.CellMouseDoubleClick
Dim ExpForm As New ExpenseEntry
My.Settings.TranCodeExpOpen =
DGVTotalReport.Rows(e.RowIndex).Cells(8).Value
If My.Settings.ExpenseForm = False Then
ExpForm.Show()
ExpForm.OpenVoucher()
My.Settings.ExpenseForm = True
Else
My.Settings.ExpenseForm = True
ExpForm.Activate()
ExpForm.OpenVoucher()
ExpForm.Refresh()
End If
End Sub

Related

Populate datagridview of another form VB.NET

In an attempt to fix my previous problem, i tried to move Form2's(contacts) load event codes to form1's background worker...The code is :
Private Sub Contact_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Con.open
dim cmd as new sqlcommand("Select * from Users",con)
Dim adapter As New SqlDataAdapter(cmd)
Dim table As New DataTable
adapter.Fill(table)
datagrid2.DataSource = table
con.Close()
datagrid2.Columns(0).Frozen = True
datagrid2.Columns(0).Width = 48
datagrid2.Columns(1).Width = 33
AddSelectAllCheckBox(datagrid2)
Dim img As DataGridViewImageColumn
img = datagrid2.Columns(1)
img.ImageLayout = DataGridViewImageCellLayout.Stretch
ExtensionMethods2.DoubleBuffered(datagrid2, True)
ExtensionMethods1.DoubleBuffered(Panel3, True)
ExtensionMethods1.DoubleBuffered(Panel9, True)
mymy1.DoubleBuffered(inpeople, True)
If datagrid2.Rows.Count <= 0 Then
added.Visible = True
Else
added.Visible = False
End If
Try
MetroComboBox2.Items.AddRange(File.ReadAllLines(Application.StartupPath + "\ct_list.ofptx"))
moneylist.Items.AddRange(File.ReadAllLines(Application.StartupPath + "\cr_list.ofptx"))
ttlist.Items.AddRange(File.ReadAllLines(Application.StartupPath + "\tt_list.ofptx"))
Catch ex As Exception
MsgBox("One or more files required by OffPo is missing/corrupted" & vbCrLf & "" & vbCrLf & "Error occured in : ct_list.ofptx or cr_list.ofptx")
End Try
entrylabel.Text = "There are/is " & datagrid2.Rows.Count & " contact entries"
svbtn.Enabled = False
upbtn.Enabled = False
dtb.Enabled = False
End Sub
To fix my previous problem(to fix the BACKGROUND WORKER FREEZING UI issue), i moved this code to the form1's BackGroundWorker's DoWork event. The code for RunCompleted event looks like this :
Private Sub BackgroundWorker2_RunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker2.RunWorkerCompleted
Contact.Show()
waiting.Hide()
End Sub
The problem is, when BackGroundWorker shows the Form2(contacts), the datagridview becomes empty.It only loads the column names but no rows/data...What am i missing ?? Why isn't the dgvw populating ?
I didn't add the BackGroundWorker Do_work event's code as it is the same as Form2's load event code

vb.net combobox to return value of another column

I have two comboboxes. The second one is dependant on the first. I then pass the selected values to a second form as objects. My code works perfectly up to here. But I also need to pass a third object to the second form (i.e. plaasnopass) based on the selection of the second combobox (i.e cmbPlaasnaam). This value however is in another column. My code below runs without errors , but the third value is not passed to the second form.
Public Class ParskaartjieKiesFrm
Dim obj As New Parskaartjies
Private Sub ParskaartjieKiesFrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'SkeduleringDatabasisDataSet.wingrd13' table. You can move, or remove it, as needed.
Me.Wingrd13TableAdapter.Fill(Me.SkeduleringDatabasisDataSet.wingrd13)
With CmbAliasnaam
.BeginUpdate()
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
Dim qry = From zc As SkeduleringDatabasisDataSet.wingrd13Row In SkeduleringDatabasisDataSet.wingrd13 _
Select zc.Aliasnaam Distinct Order By Aliasnaam
For Each ALIASNAAM As String In qry
.Items.Add(ALIASNAAM)
Next
.EndUpdate()
End With
With CmbPlaasnaam
.AutoCompleteMode = AutoCompleteMode.SuggestAppend
.AutoCompleteSource = AutoCompleteSource.ListItems
.Enabled = False
End With
End Sub
Private Sub CmbAliasnaam_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbAliasnaam.SelectedIndexChanged
obj.aliasnaampass = CmbAliasnaam.SelectedItem
With CmbPlaasnaam
.SelectedIndex = -1
.Items.Clear()
.Enabled = False
End With
If CmbAliasnaam.SelectedIndex > -1 Then
CmbPlaasnaam.BeginUpdate()
Dim Aliasnaam As String = CmbAliasnaam.Items(CmbAliasnaam.SelectedIndex).ToString
Dim qry = From zc As SkeduleringDatabasisDataSet.wingrd13Row In SkeduleringDatabasisDataSet.wingrd13 _
Where zc.Aliasnaam = ALIASNAAM Select zc.Plaasnaam Distinct _
Order By Plaasnaam
For Each plaasnaam As String In qry
CmbPlaasnaam.Items.Add(plaasnaam)
Next
If CmbPlaasnaam.Items.Count > 0 Then
CmbPlaasnaam.Enabled = True
End If
CmbPlaasnaam.EndUpdate()
End If
End Sub
Private Sub CmbPlaasnaam_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CmbPlaasnaam.SelectedIndexChanged
obj.plaasnaampass = CmbPlaasnaam.SelectedItem
obj.plaasnopass = CmbAliasnaam.SelectedValue
obj.Show()
Me.Close()
End Sub
End Class
How do I go about ?
Regards
According to your comment, I understood that you have combo box loaded from
select a from t
but this gives you single value, and you want to load
select a, b from t
and pass both values to next form.
It is helpful that you're using LINQ!! Modify it. But first declare new type
Public Class CboItem
Public Property Display As String
Public Property Value As String ' <-- any datatype
' .... any number of properties here
End Class
Dim qry =
(From zc As SkeduleringDatabasisDataSet.wingrd13Row
In SkeduleringDatabasisDataSet.wingrd13 _
Where zc.Aliasnaam = ALIASNAAM
Select New CboItem() With { .Display = zc.Plaasnaam, .Value = zs.[...] }).
Distinct(function(item)...).OrderBy(function(item)...)
CmbAliasnaam.DisplayMember = "Display"
CmbAliasnaam.ValueMember = "Value"
CmbAliasnaam.DataSource = qry.ToList()
Now you can pass to your form selected item or whatever you get out of it. for example
Dim item As CboItem = TryCast(CmbAliasnaam.SelectedItem, CboItem)
If item IsNot Nothing Then
frm.SetSelected(item.Display, item.Value, item.anyOtherProperty)
End If
' or
frm.SomeProperty = item
As you see, you can pass an object that you can store in combo box. It doesn't have to be string.

vb.net Find Form

In the Windows, the native Notepad program has a find form. Basically When the user types and hits 'Find Next', the program proceeds to find the text while keeping the focus on the Find form. This way the user can keep hitting the 'Enter' key or the button and still have the text highlighted while the form is focused.
My problem is that I have a different form for the "Search" feature and whenever the user hits "Enter" the text is found and the focus is set on the TextBox but when the user hits "Enter" again, the text gets edited because of the focus.
Currently, I'm using Regex to do this and I am using a WPF TextBox using HostElement:
Private Function GetRegExpression() As Regex
Dim result As Regex
Dim regExString As [String]
regExString = txtbx_Find.Text
If matchCaseCheckBox.Checked Then
result = New Regex(regExString)
Else
result = New Regex(regExString, RegexOptions.IgnoreCase)
End If
Return result
End Function
Private Sub FindText()
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
If isFirstFind Then
regex = GetRegExpression()
match = regex.Match(TheTextBox.Text)
isFirstFind = False
Else
match = regex.Match(TheTextBox.Text, match.Index + 1)
End If
If match.Success Then
Dim row As Integer = TheTextBox.GetLineIndexFromCharacterIndex(TheTextBox.CaretIndex)
MoveCaretToLine(TheTextBox, row + 1)
TheTextBox.SelectionStart = match.Index
TheTextBox.SelectionLength = match.Length
TheTextBox.Focus()
Me.Focus()
Else
MessageBox.Show([String].Format("Cannot find ""{0}"" ", txtbx_Find.Text), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
isFirstFind = True
End If
End Sub
Private Sub btn_FindNext_Click(sender As Object, e As EventArgs) Handles btn_FindNext.Click
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
FindText()
'theTextBox.Focus()
End Sub
I want it to be just like Notepad where the user hits "Enter" and keeps focus on the Find Form while selecting the text. How can this be achieved?
I think you should catch "keyup" event of your form like this :
Class MainWindow
Private Sub Window_KeyUp(sender As System.Object, e As System.Windows.Input.KeyEventArgs) Handles MyBase.KeyUp
If e.Key = Key.Enter Then
FindNext()
End If
End Sub
Private Sub btn_FindNext_Click(sender As Object, e As EventArgs) Handles btn_FindNext.Click
FindText()
End Sub
Private Sub FindNext()
''
Dim WpfTest1 As New SpellPad.Tb
Dim ElementHost1 As System.Windows.Forms.Integration.ElementHost = frm_Menu.Controls("ElementHost1")
Dim TheTextBox As System.Windows.Controls.TextBox = CType(ElementHost1.Child, Tb).ctrl_TextBox
''
FindText()
'theTextBox.Focus()
End Sub
End Class

When the last row in a DataGridView is selected, a value from the previous row is returned instead of from the selected row

I have a DataGridView on a form which is populated by a dataset. Everything works except one thing. In the first column I have id numbers. The user clicks on some row, and the id number from the column is taken to be deleted from the db. Every id is taking correctly except the last row - it is a new row, as you know, because the user can create new records in the database. Anyhow, if the user makes a mistake and selects this row, my code shown below somehow gets the id number from the previous row. I don't know how to avoid that issue. I am taking it using this code:
dgv.CurrentRow.Cells(0).Value
Edit:
i've added code i am using to better understand the situation:
Form Load event:
Private Sub FrmNewRodzaj_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim del As DelegateGridRefresh = New DelegateGridRefresh(AddressOf FillGrid)
Dim del2 As DelegateGridRefresh = New DelegateGridRefresh(AddressOf AlignGrid)
del = [Delegate].Combine(del, del2)
AddHandler EventGridRefresh, AddressOf del.Invoke
del.Invoke()
End Sub
Fill Grid method:
Private Sub FillGrid()
NewRodzaj = New MachineRodzaj()
dgv.DataSource = NewRodzaj.GetRodzaje.Tables(0)
End Sub
GetRodzaje method:
Public Function GetRodzaje() As DataSet
Dim con As New SqlConnection(strcon)
Dim cmd As New SqlCommand("Select * from tbMachRodzajList", con)
con.Open()
GetRodzajeDataAdapter = New SqlDataAdapter(cmd)
GetRodzajeDataAdapter.Fill(GetRodzajeDataSet, "trial1")
Return GetRodzajeDataSet
End Function
AlignGrid method:
Private Sub AlignGrid()
dgv.RowsDefaultCellStyle.BackColor = Color.SkyBlue 'LightSkyBlue
dgv.AlternatingRowsDefaultCellStyle.BackColor = Color.LightBlue
dgv.ColumnHeadersBorderStyle = DataGridViewCellBorderStyle.None
dgv.AllowUserToAddRows = True
dgv.DefaultCellStyle.Font = New Font("Tahoma", 9)
Me.dgv.DefaultCellStyle.SelectionForeColor = Color.Red
Me.dgv.DefaultCellStyle.SelectionBackColor = Color.Yellow
Me.dgv.RowHeadersVisible = False
Dim column0 As DataGridViewColumn = dgv.Columns(0)
column0.Visible = False
Dim ColNazwa As DataGridViewColumn = dgv.Columns(1)
ColNazwa.HeaderText = "Nazwa"
ColNazwa.[ReadOnly] = False
Dim ColOpis As DataGridViewColumn = dgv.Columns(2)
ColOpis.HeaderText = "Opis"
ColOpis.[ReadOnly] = False
Dim column3 As DataGridViewColumn = dgv.Columns(3)
column3.Visible = False
dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
Dim dgvColumnHeaderStyle As New DataGridViewCellStyle()
dgvColumnHeaderStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
dgv.ColumnHeadersDefaultCellStyle = dgvColumnHeaderStyle
'You cannot change the column and row header colours without disabling visual styles:
dgv.EnableHeadersVisualStyles = False
' Set the row and column header styles.
dgv.ColumnHeadersDefaultCellStyle.ForeColor = Color.WhiteSmoke
dgv.ColumnHeadersDefaultCellStyle.BackColor = Color.Firebrick
dgv.ColumnHeadersDefaultCellStyle.Font = New Font("Tahoma", 14)
End Sub
button method to save/update data:
Private Sub btnSave_Click(sender As System.Object, e As System.EventArgs) Handles btnZapisz.Click
NewRodzaj.MakeChanges()
RaiseEvent EventGridRefresh()
End Sub
MakeChanges method:
Public Sub MakeChanges()
MachineRodzajDAO.GetRodzajeMakeChanges()
End Sub
GetRodzajeMakeChanges method:
Public Sub GetRodzajeMakeChanges()
If Not GetRodzajeDataSet.HasChanges Then
MessageBox.Show("No changes no need to update", "Informacja", MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
Dim cmdbuilder As New SqlCommandBuilder(GetRodzajeDataAdapter)
Dim i As Integer
Try
i = GetRodzajeDataAdapter.Update(GetRodzajeDataSet, "trial1")
MsgBox("Updated" & i & " records")
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End Sub
so the one is missing and i am fighting with is delete button after user select row to be deleted from db and click delete button, if he select newRow then message should appear - you selected wrong row. The id values are placed within column(0) when i use CurrentRow.Cells(0).Value if user click newRow then id is id of before row so i cannot just make check if value is nothing and also IsNewRow not working.
Private Sub btnDelete_Click(sender As System.Object, e As System.EventArgs) Handles btnUsun.Click
End Sub
Hope now will be clear enough
actually isNewRow works great
put it on Event dgv.CellClick for example
If dgv.CurrentRow.IsNewRow Then
'Cancel your code
Else
'Execute your code
End If
Edit: then check the row index like
dgv.NewRowIndex
that will always be the NewRowIndex
so if a user clicks a row or NewRow that row will become CurrentRow
you could then check stuff like
If dgv.CurrentRow.Index = dgv.NewRowIndex - 1 Then
'User clicked NewRow but CurrentRow is the one before the NewRow
End If
Edit: actually this is pretty straight forward
but you have to know what is happening on your DGV.
1.
user clicks NewRow and the ClickedCell just gets selected then u get the correct RowIndex with
dgv.SelectedCells(0).RowIndex
which is the same as
BenutzerDataGridView.NewRowIndex
and CurrentRow.Index will always be -1
User clicks NewRow and start typing. Now NewRow moves one Row down and the Row which is being edited becomes CurrentRow.
that's why i added the above to always ensure that it is not the NewRow
If dgv.CurrentRow.Index = dgv.NewRowIndex - 1 Then
this should actually be enough to do what you want ^^
last EDIT:
If dgv.SelectedCells(0).RowIndex = dgv.NewRowIndex Then
MsgBox("wrong row")
End If
or this way
If dgv.Rows(dgv.SelectedCells(0).RowIndex).IsNewRow Then
MsgBox("wrong row")
End If
i'm glad u got it sorted out ^^

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