Can I re-use a form to declare multiple variables? - vb.net

I am creating a score tournament system. I have created an entry screen where a user can enter multiple scores for a group. When the submit button is pressed, I need the scores to scores to be logged so that they can go into lists on my leader board page.
Below is my current code. Is it possible to refresh the form every time the user selects submit, but also have the results from the form before it was refreshed be logged?
If not, I'm worried I would need to create a new form for each group. Surely this isn't the case?
Public Class GT_Entry
Dim Activityscore1 As Integer
Dim Activityscore2 As Integer
Dim Activityscore3 As Integer
Dim Activityscore4 As Integer
Dim Activityscore5 As Integer
Dim Groupname As String
Private Sub Submit_Click(sender As System.Object, e As System.EventArgs) Handles Submit.Click
Activityscore1 = R1S.Text
Activityscore2 = R2S.Text
Activityscore3 = R3S.Text
Activityscore4 = R4S.Text
Activityscore5 = R5S.Text
Groupname = GN.Text
GN.Clear()
R1S.Clear()
R2S.Clear()
R3S.Clear()
R4S.Clear()
R5S.Clear()
End Sub

There are several ways to approach your problem. I made a class to store the data. Then created a list of that class. Each time the user clicks Submit the data is added to the list. You can iterate the list and access the properties.
Private ScoreList As New List(Of GroupActivityScore)
Private Sub Submit_Click(sender As System.Object, e As System.EventArgs) Handles Submit.Click
Dim GAS As New GroupActivityScore
GAS.Score1 = CInt(R1S.Text)
GAS.Score2 = CInt(R2S.Text)
GAS.Score3 = CInt(R3S.Text)
GAS.Score4 = CInt(R4S.Text)
GAS.Score5 = CInt(R5S.Text)
GAS.GroupName = GN.Text
ScoreList.Add(GAS)
GN.Clear()
R1S.Clear()
R2S.Clear()
R3S.Clear()
R4S.Clear()
R5S.Clear()
End Sub
Public Class GroupActivityScore
Public Property Score1 As Integer
Public Property Score2 As Integer
Public Property Score3 As Integer
Public Property Score4 As Integer
Public Property Score5 As Integer
Public Property GroupName As String
End Class

Related

Passing data between forms DIRECTLY

I'm making a "Preference form" that will hold all the users preferences and when they go to Apply/Save I want the new values to transfer back to the main form and updateand close the form2. In the past I have done this like this:
Private Sub PreferencesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PreferencesToolStripMenuItem.Click
Preferences.Show()
End Sub
and when I click the "Apply/Save" button before it closes I would Transfer all data like this:
form1.textbox.text = form2.textbox.text
Is there anything wrong doing it this way??
What I have been reading is I should be doing it like this:
Private Sub PreferencesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PreferencesToolStripMenuItem.Click
Dim dialog As New Preferences
dialog.ShowDialog()
End Sub
And when when they click "Apply/Save" it would take all the values from Form2 and store them in a private variable (or Property) in Form2 and when that form closes I would then access the value like this:
Private Sub PreferencesToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PreferencesToolStripMenuItem.Click
Dim dialog As New Preferences
dialog.ShowDialog()
form1.textbox.text = dialog.variable
End Sub
Why would this be a better way of doing this?
UPDATE....Looking at the code below this is just a SMALL sample of all the options I will have. What is the best way to collect of the data into the object to use when serializing?
<Serializable>
Public Class Preference
#Region "Properties"
Public Property ScaleLowest As String = "5"
Public Property ScaleHighest As String = "200"
Public Property ScaleInc As String = "5"
Public Property ThickLowest As Double = 0.125
Public Property ThickHighest As Double = 4
Public Property ThickInc As Double = 0.125
Public Property WidthLowest As Double = 0.125
Public Property WidthHighest As Double = 0.6
Public Property WidthInc As Double = 0.125
Public Property LengthLowest As Double = 1
Public Property LengthHighest As Double = 96
Public Property LengthInc As Double = 1
Public Property FractionON As Boolean = False
Public Property DecimalON As Boolean = True
Public Property ColorSelection As String = "Colors"
Public Property FinalColor As String = "255, 255, 0"
Public Property roughColor As String = "255, 255, 100"
Public Property SplashON As Boolean = False
Public Property LogInON As Boolean = False
#End Region
Public Sub New()
'for creating new instance for deserializing
End Sub
Public Sub GatherAllData()
'Save Defaults
SaveSerializeObj()
End Sub
Public Sub SaveSerializeObj()
'Get Changes?????
'Serialize object to a text file.
Dim objStreamWriter As New StreamWriter("C:\Users\Zach454\Desktop\test.xml")
Dim x As New XmlSerializer(Me.GetType)
x.Serialize(objStreamWriter, Me)
objStreamWriter.Close()
End Sub
Public Function LoadSerializeObj() As Preference
'Check if new file need created
If File.Exists("C:\Users\454\Desktop\test.xml") = False Then
SaveSerializeObj()
End If
'Deserialize text file to a new object.
Dim objStreamReader As New StreamReader("C:\Users\454\Desktop\test.xml")
Dim newObj As New Preference
Dim x As New XmlSerializer(newObj.GetType)
newObj = CType(x.Deserialize(objStreamReader), Preference)
objStreamReader.Close()
Return newObj
End Function
The best option is to create a class that would have properties for your form controls. Then you can store these properties and then access these when needed.
Also there's really no reason to be passing data back and forth, you can store this data off somewhere (database, file, mysettings etc) and then load this data up into a class. Then you can store and retrieve data from this class. Then if you need to save data back to somewhere you have a class object to use.
Here is a short example to show how you can create another form (Preferences) click save and then show those values back on the other form (calling form).
This is the main form
Public Class Form1
Public _frm2 As Form2
Private Sub btnShowPreferences_Click(sender As Object, e As EventArgs) Handles btnShowPreferences.Click
Using _frm2 As New Form2()
'if we clicked save on the form then show the values in the
'controls that we want to
If _frm2.ShowDialog() = Windows.Forms.DialogResult.OK Then
txtFirstName.Text = _frm2._Preferences.FirstName
txtLastName.Text = _frm2._Preferences.LastName
End If
End Using
End Sub
End Class
Here is an example (Preferences) class
This class would hold all your properties for the preferences. This is an example, you can change anything you need to suit your needs.
Option Strict On
Public Class Preferences
#Region "Properties"
Public Property FirstName As String
Public Property LastName As String
#End Region
Public Sub New()
End Sub
End Class
The second Form could be your (Preference) form with all the controls a user would need to interact with.
Public Class Form2
Public _Preferences As New Preferences 'create class variable you can use for later to store data
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
'set your properties of the class from your form. this will then hold everything you can get from
'the first form...
With _Preferences
.FirstName = txtFirstName.Text
.LastName = txtLastName.Text
End With
Me.DialogResult = Windows.Forms.DialogResult.OK 'this is used to determine if user clicked a save button...
End Sub
End Class
I hope this get's you started, if you do not understand something please let me know.
To directly answer your question, the main difference in your two code samples is that the second uses ShowDialog to open the form modally, vs the first sample which lets you interact with the parent form while the second is open.
The second approach may be better from the view of user flow control. If your real question is whether to push data back to the main form or pull data from the dialog, it is probably better to pull from the dialog. This approach makes the dialog reusable from other forms.

Populate datagrid with items based on a name vb.net

I have a code that basically gets me the index of a hidden combobox I then use that index to populate a datagrid, however I only want to show the items which correspond to the text in the lbl_test.text label.
Private Sub CBX_Doctors_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CBX_Doctors.SelectedIndexChanged
lbl_test.Text = CBX_Doctors.SelectedItem.ToString
CBX_hidden.SelectedItem = lbl_test.Text
lbl_hidden.Text = CBX_hidden.SelectedIndex.ToString
Dim app = Convert.ToInt32(lbl_hidden.Text)
DGV_1.DataSource = AppointmentList
End Sub
Public Class Appointment
Property AppointmentID As String
Property AppointmentDate As String
Property Time As String
Property AppointmentLength As Integer
Property DoctorName As String
Property PatientName As String
Property Reason As String
End Class
This was a requested portion of the code responsible for saving to an xml file:
'save to the xml
Dim objStreamWriter4 As New StreamWriter("..\..\..\Appointments.xml")
Dim a As New XmlSerializer(AppointmentList.GetType)
a.Serialize(objStreamWriter4, AppointmentList)
objStreamWriter4.Close()
It sounds like you want to filter the return list based on one of the fields equals the lbl_test.Text - if that is correct then you could do something like:
Private Sub CBX_Doctors_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CBX_Doctors.SelectedIndexChanged
Dim doctorName = CBX_Doctors.SelectedItem.ToString
CBX_hidden.SelectedItem = doctorName
lbl_hidden.Text = CBX_hidden.SelectedIndex.ToString
DGV_1.DataSource = AppointmentList.Where(Function(apt) apt.DoctorName = doctorName)
End Sub

add a table of Structures to a listbox vb.net

i have a structure in a module that i instanciate a table of its type
Public Structure Client
Public _nom As String
Public _prenom As String
Public _age As Integer
End Structure
Module Module1
Public TableauClient(0) As Client
End Module
that i need to populate nd resize every time i hit a certain button
Dim Dimension As Integer = 0
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TableauClient(Dimension)._nom = TextBox1.Text.ToString()
TableauClient(Dimension)._prenom = TextBox2.Text.ToString()
TableauClient(Dimension)._age = Val(TextBox3.Text)
Dimension += 1
ReDim TableauClient(Dimension)
End Sub
the problem is i need to fill a listbox with all the elements in the table when i hit another button but i don't even know where to start to do this, tried datasource or add item by item by using concatenations between the three fields but still couldn't get it right
you can still use the structure but, I think it will be easier to work with class. Instead of Array make a list
dim TableauClient as new List(of Client)
create toString inside your class / structure
Public Overrides Function ToString() As String
return _nom
End Function
and just add those into your listbox
listbox.items.add(TableauClient (0))

I want my structure of vehicle makes to show in a listbox

I'm not sure what to change in my code to make the listbox show each vehicle make.
Public Class Form1
Structure Vehicle
Dim Make As String
Dim Model As String
Dim Doors As Integer
Dim Hp As Integer
Dim VIN As String
End Structure
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
Dim Vehicles(9) As Vehicle
Vehicles(0).Make = "Chevrolet"
Vehicles(1).Make = "Dodge"
Vehicles(2).Make = "Nissan"
Vehicles(3).Make = "Mitsubishi"
Made a for loop to show each make
For i = 0 To 4 Step 1
ls.Items.Add(Vehicles(i).Make.ToString)
Next
End Sub
You're only supplying data to 4 instances (0-3):
Vehicles(0).Make = "Chevrolet"
Vehicles(1).Make = "Dodge"
Vehicles(2).Make = "Nissan"
Vehicles(3).Make = "Mitsubishi"
But you're trying to retrieve data from 5 instances (0-4):
For i = 0 To 4 Step 1
String is by default Nothing unless you assign it a value. So your 5th instance is an empty instance of Vehicle. Thus...
This will fail because Vehicles(4).Make is Nothing, and you can't call a method (ToString) on Nothing:
ls.Items.Add(Vehicles(i).Make.ToString)
And this will fail because Vehicles(4).Make is Nothing, and you can't add an empty or null string to a listbox:
ls.Items.Add(Vehicles(i).Make)
You need to either:
Adjust your loop to only cover the data you have (For i = 0 To 3 Step 1), or
Add another data element (Vehicles(4).Make = "Something"), or
Add null checking to your code (If Vehicles(i).Make Is Not Nothing)
Why don't you try using Class instead of Structure, and using list instead of array. Since it seems that yourself also don't how long will the data be, so in this case list is a good choice for your and you can just consider it as a dynamic array in c/c++. Following is my way to interpret
Public Class Form1
Class Vehicle
Dim Make As String
Dim Model As String
Dim Doors As Integer
Dim Hp As Integer
Dim VIN As String
Public Sub New(Dim s As String)
Me.Model=s
End Sub
End Class
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
Dim Vehicles As New List(Of Vehicle)
Vehicles.Add(New Vehicle("Chevrolet"))
Vehicles.Add(New Vehicle("Dodge"))
Vehicles.Add(New Vehicle("Nissan"))
Vehicles.Add(New Vehicle("Mitsubishi"))
And when you loop it,
Dim car as Vehicle
For each car in Vehicles
ls.Items.Add(car.Make)
Next
Hope it helps.

Visual Basic keeps reseting my variables to 0 each time I leave and re-enter a class

I have a form to obtain financial information from the user including a loan amount, rate, and term. I'm supposed to call a class to do the work and then return the answer to the form. However, for some reason, whenever my program moves out of the class, back to the form, then back to the class, the variables I have the class get reset to 0. My code is below. Any help would be awesome.
This is the code from my form:
'Preform calculation when button is clicked
Private Sub buttonCalc_Click(sender As Object, e As EventArgs) Handles buttonCalc.Click
Dim loanAmount As New finClass
Dim rate As New finClass
Dim term As New finClass
Dim payment As New finClass
loanAmount.getLoanAmount = textBoxMortgageAmount.Text
rate.getAnnualRate = comboBoxAnnualRate.Text.Replace("%", "")
term.getTermInYears = comboBoxTerm.SelectedItem
textBoxMonthlyPayment.Text = payment.setMonthlyPayment
End Sub
And this code from the associated class:
Public Class finClass
Private loanAmt As Decimal
Private termValue As Decimal
Private rateValue As Decimal
Public paymentValue As Decimal
Public WriteOnly Property getLoanAmount
Set(value)
If IsNumeric(value) AndAlso value > 1000 AndAlso value < 10000000 Then
Me.loanAmt = value
Else
MessageBox.Show("Mortgage amount must be a number between $1,000 and $10,000,000", "Invalid Number", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Set
End Property
Public WriteOnly Property getAnnualRate
Set(value)
rateValue = value.Replace("%", "")
If rateValue < 1 Then
rateValue *= 100
End If
End Set
End Property
Public WriteOnly Property getTermInYears
Set(value)
termValue = value
End Set
End Property
Public ReadOnly Property setMonthlyPayment
Get
Return -Pmt((rateValue / 1200), termValue * 12, Me.loanAmt)
End Get
End Property
End Class
I don't work in VS but it looks like you are creating four instances of the class. I'm pretty sure this is not correct.
Private Sub buttonCalc_Click(sender As Object, e As EventArgs) Handles buttonCalc.Click
Dim loanAmount As New finClass '## Creates NEW finClass object
Dim rate As New finClass '## Creates NEW finClass object
Dim term As New finClass '## Creates NEW finClass object
Dim payment As New finClass '## Creates NEW finClass object
loanAmount.getLoanAmount = textBoxMortgageAmount.Text
rate.getAnnualRate = comboBoxAnnualRate.Text.Replace("%", "")
term.getTermInYears = comboBoxTerm.SelectedItem
textBoxMonthlyPayment.Text = payment.setMonthlyPayment
End Sub
So each of those objects is a different instance of a finClass object. So each time you "re-enter" the class, you're actually entering a different instace of that class object, which is why all the variables are value = 0. They have not been instantiated or set, yet.
Try this instead, to create one class object which you manipulate with the methods in your class module:
Private Sub buttonCalc_Click(sender As Object, e As EventArgs) Handles buttonCalc.Click
Dim objFinClass as New finClass
objFinClass.getLoanAmount = textBoxMortgageAmount.Text
objFinClass.getAnnualRate = comboBoxAnnualRate.Text.Replace("%", "")
objFinClass.getTermInYears = comboBoxTerm.SelectedItem
textBoxMonthlyPayment.Text = objFinClass.setMonthlyPayment
End Sub
Create a module and use 'Public' to dimension your variables
Public Module Example
Public ExampleVariable as Integer
End Module
This will allow the variable to retain its value for as long as the program is running. Using dim inside the form class will cause the value to redimension every time the form is loaded