Access a panel from another form with increment variable name - vb.net

Public Sub StatusLoad(ByVal id As String)
''Dim F As New Apps
''Dim W As Panel = DirectCast(F.Controls(id), Panel)
Dim count As Long = 0
Dim strQueryStat As String = "SELECT * FROM sample_db.ronda WHERE id = '" + id + "'"
Dim SqlCmdStat As New MySqlCommand(strQueryStat, dbCon)
Reader = SqlCmdStat.ExecuteReader
While Reader.Read
count = count + 1
MsgBox("id" & count)
Dim status_db = Reader.GetString("status")
If status_db = 0 Then
Apps.id.BackColor = Color.Green '<------
MsgBox("Green")
Else
Apps.BackColor = Color.Red
MsgBox("Red")
End If
End While
End Sub
I want to use 'id' variable that get from other form to find the panel name from the other form. the above code is in a class. the panel that i want to access is at another form.
at the other for i send "con.StatusLoad(id)". the name of panel is id1 , id2 , id3 ...... the error is at the arrow
Private Sub app_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
con.ManageConnection(False)
For index As Integer = 1 To 2
Dim id As String = "id" & index
con.StatusLoad(id)
Next index
End Sub

Each control, including forms, has a Controls property that contains a collection of child controls. You can index that collection by ordinal or name, e.g.
For i = 1 To 5
Dim pnl = Me.Controls("Panel" & i)
'...
Next
Note that you'll be getting a Control reference back, so you can only use it to access members of the Control class. If you want to access members of a specific type of control then you must cast as that type.
Controls is a public member so it can be accessed from outside the form but probably shouldn't be. The same "rules" apply as would always apply to making changes to controls on a form, i.e. best practice dictates that it's done inside that form only.

Related

Read data from dynamically created text-box

I'm trying to collect data after creating dynamic text-box with vb.net
Private Sub btn_OK_lines_number_Click(sender As Object, e As EventArgs)
Handles btn_OK_lines_number.Click
Dim i As Integer
Dim x As Integer
Dim Z As Integer
Z = 150
If IsNumeric(txt_lines_number.Text) Then
Int32.TryParse(txt_lines_number.Text, x)
For i = 1 To x
Dim newTB As New TextBox
Dim newLB As New Label
newLB.Name = "lbl_workstation_number_line" & i
newLB.Text = "Nbr Work Station in Line" & i
newLB.Size = New Size(190, 20)
newLB.ForeColor = Color.White
newLB.Font = New Font("consolas", 12, FontStyle.Regular, GraphicsUnit.Pixel)
newLB.Location = New Point(20, Z + i * 30)
newTB.Name = "Textbox" & i
newTB.Size = New Size(170, 20)
newTB.Location = New Point(200, Z + i * 30)
Me.Controls.Add(newTB)
Me.Controls.Add(newLB)
Next
i = i + 1
Else
MessageBox.Show("please enter a number")
txt_lines_number.Text = ""
End If
End Sub
Let's say you just have one row, and only create one TextBox. You set the name here:
newTB.Name = "Textbox" & i
where the resulting TextBox is named Textbox1. The problem is you can't just reference the identifier Textbox1 directly in your code, as you do with txt_lines_number. You can't even reference it as a member of the class (Me.Textbox1). This name didn't exist at compile time, and so it's not an identifier you can use, and it's not a member of the class at all. There was never a matching Dim statement for that name.
What you can do, though, is look again in the Controls collection where you added the TextBox to the form:
Me.Controls("Textbox1")
or
Me.Controls("Textbox1").Text
You may also need to cast the value to a TextBox:
Dim box As TextBox = DirectCast(Me.Controls("Textbox1"), TextBox)
MessageBox.Show(box.Text)
Remember that case matters here.
Further saving this in a DB is out of scope for one question. There are as many ways to do that as there are programmers in the world. You should make your own attempt first, and come back here with a new question when you run into specific problems.
Thank you,
this is my attempt and it is done !
Dim userInput As TextBox = Form1.Controls.Item("TextBox" & i.ToString)
mycommand.Parameters.AddWithValue("#workstation", userInput.Text)
:D
Because you creating dynamic amount of input controls, right tool for the job will be DataGridView control.
Create a class to represent your data
Public Class LineInfo
Public Property Number As Integer
Public Property WorkStationNumber As Integer
End Class
Create `DataGridView in the form designer.
Private Sub btn_OK_lines_number_Click(sender As Object, e As EventArgs) Handles btn_OK_lines_number.Click
Dim linesAmount As Integer
If Integer.TryParse(txt_lines_number.Text, linesAmount) = False Then
MessageBox.Show("please enter a number")
txt_lines_number.Text = ""
Exit Sub
End If
' Create class instance for every line
Dim lines =
Enumerable.Range(1, linesAmount)
.Select(Function(i) New LineInfo With { .Number = i })
.ToList()
'Set lines as DataSource to the DataGridView
Me.DataGridView1.DataSource = lines
End Sub
DataGridView will display all lines and provide input fields to update work station numbers.
You can access updated lines later by casting DataSource back to the List
Dim lines = DirectCast(Me.DataGridView1.DataSource, List(Of LineInfo))
' Now you can access all data and save it to the database
Dim parameters =
lines.Select(Function(line)
Return new SqlParameter With
{
.ParameterName = $"#workstation{line.Number}",
.SqlDbType = SqlDbType.Int,
.Value = line.WorkStationNumber
}
End Function)
.ToList()
myCommand.Parameters.AddRange(parameters)
You can freely change style, font colors of different columns in the datagridview.

Binary Search or Insertion Sort with list view [Visual Basic .net]

Recently when creating a program for my client as part of my computing project in visual basic .net I've came across a problem, which looks like following; In order to receive additional marks for my program I must take an advantage of either Binary Search or Insertion Sort subroutine declared recursively, so far the only place I can use it on is my View form which displays all reports generated by program but the problem with this is since I'm using MS Access to store my data all of the data is downloaded and placed in listview in load part of form. So the only way I can use it is by running it on listview which is a major problem for me due to the fact that I'm not very experienced in vb.
For binary search I have tried downloading all of the items in specified by user column into an array but that's the bit I was struggling on the most because I'm unable to download all items from only one column into an array. Also instead of searching every single column user specifies in my form in which column item is located (For example "19/02/2013" In Column "Date"), In my opinion if I manage to download every single entry in specified column into an array it should allow me to run binary search later on therefore completing the algorithm. Here's what I've got so far.
Sub BinarySearch(ByVal Key As String, ByVal lowindex As String, ByVal highindex As String, ByVal temp() As String)
Dim midpoint As Integer
If lowindex > highindex Then
MsgBox("Search Failed")
Else
midpoint = (highindex + lowindex) / 2
If temp(midpoint) = Key Then
MsgBox("found at location " & midpoint)
ElseIf Key < temp(midpoint) Then
Call BinarySearch(Key, lowindex, midpoint, temp)
ElseIf Key > temp(midpoint) Then
Call BinarySearch(Key, midpoint, highindex, temp)
End If
End If
End Sub
Private Sub btnSearch_Click(sender As System.Object, e As System.EventArgs) Handles btnSearch.Click
Dim Key As String = txtSearch.Text
Dim TargetColumn As String = Me.lstOutput.Columns(cmbColumns.Text).Index
Dim lowindex As Integer = 0
Dim highindex As Integer = lstOutput.Items.Count - 1
'Somehow all of the items in Target column must be placed in temp array
Dim temp(Me.lstOutput.Items.Count - 1) As String
' BinarySearch(Key, lowindex, highindex, temp)
End Sub
For Insertion sort i don't even have a clue how to start, and the thing is that I have to use my own subroutine instead of calling system libraries which will do it for me.
Code which I have to use looks like following:
Private Sub InsertionSort()
Dim First As Integer = 1
Dim Last As Integer = Me.lstOutput.
Dim CurrentPtr, CurrentValue, Ptr As Integer
For CurrentPtr = First + 1 To Last
CurrentValue = A(CurrentPtr)
Ptr = CurrentPtr - 1
While A(Ptr) > CurrentValue And Ptr > 0
A(Ptr + 1) = A(Ptr)
Ptr -= 1
End While
A(Ptr + 1) = CurrentValue
Next
Timer1.Enabled = False
lblTime.Text = tick.ToString
End Sub
Any ideas on how to implement this code will be very appreciated, and please keep in my mind that I'm not very experienced in this language
Perhaps this might give you a place to begin. If you already have a ListView with "stuff" in it you could add a button to the form with the following code to copy the Text property for each item into an array:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myArray(Me.ListView1.Items.Count - 1) As String
Dim i As Integer
' load array
For i = 0 To Me.ListView1.Items.Count - 1
myArray(i) = Me.ListView1.Items(i).Text
Next
' show the results
Dim s As String = ""
For i = 0 To UBound(myArray)
s &= String.Format("myArray({0}): {1}", i, myArray(i)) & vbCrLf
Next
MsgBox(s, MsgBoxStyle.Information, "myArray Contents")
' now go ahead and manipulate the array as needed
' ...
End Sub

List view sort arrow vb.net

i am trying to draw sort arrows on list view column header along with the default visual styles
so far i have got this
Private Sub List_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles List.DrawColumnHeader
e.DrawDefault = True
If e.ColumnIndex = selectedIndex Then
e.Graphics.DrawImage(ImageList1.Images(1), CType(e.Bounds.Left + e.Bounds.Width / 2, Single) - 5, -2)
End If
End Sub
but the visual style is drawn over the arrow somehow
so i figured i could try this :
Private Sub List_DrawColumnHeader(sender As Object, e As DrawListViewColumnHeaderEventArgs) Handles List.DrawColumnHeader
e.DrawDefault = True
If lastDrawn.ColumnIndex = selectedIndex Then
e.Graphics.DrawImage(ImageList1.Images(1), CType(lastDrawn.Bounds.Left + lastDrawn.Bounds.Width / 2, Single) - 5, -2)
End If
lastDrawn=e
End Sub
and it draws the arrow when the next corresponding column is being drawn
but with this i cant get it to draw for the last column
Screenshots:
In order to use the .NET build in solution for showing a custom icon for a list view column header you need to:
create an ImageList
add three images (up / down arrow and empty) to it
bind the image list to the ListView control
bind to the ColumnClick event of the ListView control
when sorting the columns set the ImageKey property of the currently sorted column depending on the sorting direction
This example class (a simple form) shows how to set the images correctly not using custom drawing for the ListView header columns.
It does not implement any sort! (how to implement a ListViewSorter is shown in this MSDN article)
You need to implement a custom ListView-Sorter class and retrieve the image or the image key from it, after a column is sorted.
Public Class SimpleForm
Inherits Form
Private sortItems = New ImageList()
Dim lv As ListView = New ListView()
Dim so = System.Windows.Forms.SortOrder.Ascending
Public Sub New()
' create columns, items and ListView
Dim columns = New List(Of ColumnHeader)
Dim c1 = New ColumnHeader()
c1.Name = "c1"
c1.Text = "Name"
Dim c2 = New ColumnHeader()
c2.Name = "c2"
c2.Text = "Type"
columns.Add(c1)
columns.Add(c2)
Dim items = New List(Of ListViewItem)
Dim i1 = New ListViewItem("Terminator")
i1.SubItems.Add("T1000")
Dim i2 = New ListViewItem("Terminator")
i2.SubItems.Add("T10")
Dim i3 = New ListViewItem("J.C.")
i3.SubItems.Add("Human")
items.Add(i1)
items.Add(i2)
items.Add(i3)
' init and bind column click
lv.Columns.AddRange(columns.ToArray())
lv.Items.AddRange(items.ToArray())
lv.SmallImageList = sortItems
lv.View = View.Details
lv.Dock = DockStyle.Fill
Controls.Add(lv)
AddHandler lv.ColumnClick, AddressOf clickEventHandler
' init images list
sortItems.TransparentColor = System.Drawing.Color.Transparent
sortItems.Images.Add("up", Image.FromFile("d:\temp\32\arrow_up.gif"))
sortItems.Images.Add("down", Image.FromFile("d:\temp\32\arrow_down.gif"))
sortItems.Images.Add("empty", Image.FromFile("d:\temp\32\check.gif"))
End Sub
Private Sub clickEventHandler(ByVal o As Object, ByVal e As ColumnClickEventArgs)
' Implement a custom ListViewItemSorter and fetch the icon from it!
' Set the ListViewItemSorter property to a new ListViewItemComparer
' object. Setting this property immediately sorts the
' ListView using the ListViewItemComparer object.
' THIS CODE SHOWS ONLY HOW TO SET THE SORT ICON!
For i As Integer = 0 To lv.Columns.Count - 1
If (i = e.Column) Then
Select Case (so)
Case System.Windows.Forms.SortOrder.Ascending
lv.Columns(i).ImageKey = "up"
so = System.Windows.Forms.SortOrder.Descending
Case System.Windows.Forms.SortOrder.Descending
lv.Columns(i).ImageKey = "down"
so = System.Windows.Forms.SortOrder.Ascending
Case Else
lv.Columns(i).ImageKey = "empty"
so = System.Windows.Forms.SortOrder.None
End Select
Else
lv.Columns(i).ImageKey = "empty"
End If
Next i
End Sub
End Class
The output looks like this:

DataGridView not Refreshing/Updating/Reloading Data. After Child form closes

This is a VB.NET, Winforms App. I have a datagridview on "Form1" that uses a databinding.datasource which is an Entity Framework table. I fill the datagridview with the below function on Form1:
Sub PM_UnitViewGrid()
Try
_form1.UnitsBindingSource.DataSource = db.units.Where(Function(f) f.propertyId = _form1.CurrentPropertyId).OrderBy(Function(F) F.unitNumber)
_form1.UnitDataGridView.DataSource = _form1.UnitsBindingSource.DataSource
Dim iCount As Integer = _form1.UnitDataGridView.RowCount
For x As Integer = 0 To iCount - 1
If Not IsNothing(_form1.UnitDataGridView.Rows(x).Cells(4).Value) Then
Dim tid As Integer = _form1.UnitDataGridView.Rows(x).Cells(4).Value
Dim _ten As tenant = db.tenants.Single(Function(f) f.Occupantid = tid)
_form1.UnitDataGridView.Rows(x).Cells(1).Value = _ten.first_name + ", " + _ten.last_name
Else
Dim btnColumn As DataGridViewButtonCell = CType(_form1.UnitDataGridView.Rows(x).Cells(1), DataGridViewButtonCell)
btnColumn.Style.BackColor = Color.Green
_form1.UnitDataGridView.Rows(x).Cells(1).Value = "VACANT"
End If
Next
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Return
End Sub
This works great and also assigns the needed values to an unbound column. The problem is that the cells(1) is a button. Which when clicked takes the user to another form as a new dialog window. The function for which is below. However, once the changes are made in that form I need for the datagridview to refresh the data that its using from the database and show the correct data. As it stands right now the values are not updating on the datagridview unless the app is completely exited and restarted. Nothing I have found seems to work and Refresh and Update only redraw the control. I need the underlying datasource to refresh and then the datagridview once the child form is exited.. This has had me stumped for a good 36 hours now and I am lost as to why nothing I am trying is working. ANY and all help would be greatly appreciated.
The sub that loads the child form based on the cells(1) button clicked is as follows:
Private Sub UnitDataGridView_CellContentClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles UnitDataGridView.CellContentClick
UnitDataGridView.CommitEdit(DataGridViewDataErrorContexts.CurrentCellChange)
Dim y As DataGridViewCellEventArgs = e
Dim Tid As Integer = Nothing
If e.ColumnIndex = 1 Then
If Not e.RowIndex = -1 Then
If Not IsNothing(UnitDataGridView.Rows(e.RowIndex).Cells(4).Value) Then
currentTenent = UnitDataGridView.Rows(e.RowIndex).Cells(4).Value
TenentIdentification = currentTenent
If Not IsNothing(e) Then
If Not IsNothing(UnitDataGridView.Rows(e.RowIndex).Cells(4).Value) Then
Tid = UnitDataGridView.Rows(e.RowIndex).Cells(4).Value
Dim _ten As tenant = db.tenants.Single(Function(f) f.Occupantid = Tid) 'tenant is a table entity
TenantViewSubs.tenId = _ten.Occupantid
Dim t As New TenantView
t.tenId = tid
t.ShowDialog()
End If
End If
PropertyManagSubs.PM_UnitViewGrid() 'This is the function that is above that fills the datagridview
Else
Dim uTview As New UnassignedTenants
uTview.selectedProperty = selectedProperty 'selectedProperty is Integer
uTview.ShowDialog()
PropertyManagSubs.PM_UnitViewGrid() 'This is the function that is above that fills the datagridview
End If
End If
End If
End Sub
I tried each of the following code blocks after the t.ShowDialog() line with no change at all.
UnitDataGridView.Refresh()
.
UnitsBindingSource.Dispose()
UnitsBindingSource.DataSource = db.units.Where(Function(f) f.propertyId = selectedProperty).OrderBy(Function(f) f.unitNumber)
UnitDataGridView.DataSource = UnitsBindingSource.DataSource
.
UnitsBindingSource.DataSource = nothing
unitsBindingSource.DataSource = db.units.Where(Function(f) f.propertyId = selectedProperty).OrderBy(Function(f) f.unitNumber)
UnitDataGridView.DataSource = UnitsBindingSource.DataSource
I finally fixed this on my own.. It was in the way I passed my db context to the databinding..
I simply wrote the below sub:
Private Sub UpdateValues()
Dim context As New storageEntities 'storageEntities is an Entity
Dim query = context.units.Where(Function(F) F.propertyId = selectedProperty).OrderBy(Function(f) f.unitNumber)
UnitDataGridView.DataSource = query
End Sub
Then anytime a child form updated data I simply call
UpdateValues()
After the dialog box closes.
This may help someone else with the same problems so that is why I am posting it.

Public subs don't work in this scenario

I have a form named FrmDrvouchers. It contains some public subprocedures.
I call these subs from another form which opens from a form which is opened from FrmDrVouchers as a dialog.
When I open FrmDrvouchers directly, everything works. But when I call FrmDrvouchers from another project which is also part of this solution, its public subs don't work when I call them from another (dialog) form.
Here is the code of the Button Click from which I open FrmDrvouchers:
Dim FrmDrv As FrmDrVouchers = New FrmDrVouchers()
FrmDrv.Show()
This works, but those public subs don't. Why?
Thanks For ur response,
It just skip what i want to do, but not throws any Exceptions,
Now I m posting my Code,,, plz have a look on that,,
Here is my Main form's MenuStrip Button Click code :
Private Sub CashPaymentToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CashPaymentToolStripMenuItem.Click
Dim DrVouchers As Transactions.FrmDebitVouchers = Transactions.New FrmDebitVouchers()
DrVouchers.Show()
End Sub
Here is the FrmDebitVouchers's Public Subs which are not working,,, in the sense that they skip the function which i have written but not throwing any Exception,,
Public Sub DrVoucherOPen(ByVal VoucherNo As Integer)
'Filling the Dataset with selected Voucher No to OPen the record
DebitVouchersTableAdapter.FillByVoucher(Flr12131DataSet.DebitVouchers, VoucherNo)
VoucherDateDateTimePicker.Enabled = False
End Sub
Public Sub DrVoucherBodyOPen(ByVal VoucherNo As Integer)
'---------Procedure to Open DrVouchersBody And to OPen it in Datagridview-------------'
'Getting the User No, and if it is admin then load fill dataset and allow user to edit the record
If GetUserNumber() = 1 Then
'Filling the dataset
DebitVouchersBodyTableAdapter.FillByVoucher(Flr12131DataSet.DebitVouchersBody, VoucherNo)
DrBodyDGV.DataSource = Nothing
Dim Sum As New Decimal
'Initializing the SerialNumbers variable
SerialNumbers = New List(Of Integer)
'Setting datagridview to opend record
For i = 0 To Flr12131DataSet.DebitVouchersBody.Rows.Count - 1
DrBodyDGV.Rows.Add()
DrBodyDGV.Rows(i).Cells(0).Value = Flr12131DataSet.DebitVouchersBody.Rows(i).Item("SerialNo")
DrBodyDGV.Rows(i).Cells(3).Value = Flr12131DataSet.DebitVouchersBody.Rows(i).Item("AccountNo")
DrBodyDGV.Rows(i).Cells(6).Value = Flr12131DataSet.DebitVouchersBody.Rows(i).Item("Debit")
DrBodyDGV.Rows(i).Cells(7).Value = Flr12131DataSet.DebitVouchersBody.Rows(i).Item("Narration")
'Getting serial No into List
SerialNumbers.Add(Flr12131DataSet.DebitVouchersBody.Rows(i).Item("SerialNo"))
'Getting Account Name into Datagridview
If Not Not IsNumeric(DrBodyDGV.Rows(i).Cells(3).Value) Then
Dim Qa As New Flr12131DataSetTableAdapters.QueriesTableAdapter
Dim StrAccountName = Qa.GetAccountName(DrBodyDGV.Rows(i).Cells(3).Value)
DrBodyDGV.Rows(i).Cells(5).Value = StrAccountName
Else
End If
Sum += DrBodyDGV.Rows(i).Cells(6).Value
Next
TxtTotal.Text = Sum
'Setting the controls properties for admin
DrBodyDGV.AllowUserToAddRows = True
DrBodyDGV.AllowUserToDeleteRows = True
DrBodyDGV.ReadOnly = False
BtnSave.Enabled = True
BtnDelete.Enabled = True
BtnPrint.Enabled = True
ToUpdate = True
Else
'If user is not admin then load all record and not allow user to modify it or delete
' Bounding the datagridview
Dim Sum As Decimal = 0
BtnSave.Enabled = False
DebitVouchersBodyTableAdapter.FillByVoucher(Flr12131DataSet.DebitVouchersBody, VoucherNo)
DrBodyDGV.DataSource = Flr12131DataSet.DebitVouchersBody
For i = 0 To DrBodyDGV.Rows.Count - 1
If Not Not IsNumeric(DrBodyDGV.Rows(i).Cells(3).Value) Then
Dim Qa As New Flr12131DataSetTableAdapters.QueriesTableAdapter
Dim StrAccountName = Qa.GetAccountName(DrBodyDGV.Rows(i).Cells(3).Value)
DrBodyDGV.Rows(i).Cells(5).Value = StrAccountName
Else
End If
Sum += DrBodyDGV.Rows(i).Cells(6).Value
Next
TxtTotal.Text = Sum
DrBodyDGV.AllowUserToAddRows = False
DrBodyDGV.AllowUserToDeleteRows = False
' DrBodyDGV.edit()
DrBodyDGV.ReadOnly = True
BtnSave.Enabled = False
BtnDelete.Enabled = False
BtnPrint.Enabled = True
End If
End Sub
Here is another the DrVouchersRecord form from which I call Public Subs:
Private Sub DrVouchersRecordDataGridView_CellDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DrVouchersRecordDataGridView.CellDoubleClick
Dim FrmDrVouchers As FrmDebitVouchers = New FrmDebitVouchers()
If FrmDrVouchers.DrBodyDGV.Rows.Count > 1 Then
Dim Ans As Integer
Ans = MsgBox("Unsaved changes will be lost, want to proceed", vbYesNo + vbInformation, "Alert")
If Ans = vbYes Then
Dim VoucherNo As New Integer
VoucherNo = DrVouchersRecordDataGridView.CurrentRow.Cells(0).Value
FrmDrVouchers.DrVoucherOPen(VoucherNo)
FrmDrVouchers.DrVoucherBodyOPen(VoucherNo)
Me.Close()
End If
Else
Dim VoucherNo As New Integer
VoucherNo = DrVouchersRecordDataGridView.CurrentRow.Cells(0).Value
FrmDrVouchers.DrVoucherOPen(VoucherNo)
FrmDrVouchers.DrVoucherBodyOPen(VoucherNo)
Me.Close()
End If
End Sub
My forms sequence is:
FrmMain is my main startUp form
After that FrmDebitVouchers Open on menustripButtonclick
After that DebitVouchersRecord is Open as Dialog from DrmDebitVouchers,,, and from these Public Subs are called
I Have added Refrence also
Waiting for ur answers,
This problem has hit many programmers coming from VB6 to VB.NET.
In your DataGridView_DoubleCellClick event you create a NEW instance of FrmDebitVouchers.
Then your code refers to property/methods/objects of this new INSTANCE, not of the original one created via CashPaymentToolStripMenuItem_Click. (Also note that this new instance is never showed on the screen, so you are sending/requesting changes to an hidden form instance)
Of course, the DrBodyDGV.Rows.Count is zero on this INSTANCE (referenced as FrmDrVouchers) because probably this INSTANCE has never been intialized like the first one.
Try to add a FrmDrVouchers.Show() after the creation and you will see the hidden SECOND INSTANCE of the form class FrmDebitVouchers.
To solve your problem, you need to pass the reference of the first FrmDebitVouchers instance to the DrVouchersRecord form (for example in the constructor or via a public property) and then use that reference instead of creating FrmDrVouchers