How do i get the object from one sub to the other sub - vb.net

What i am trying to do is to get the intGuestID1 from page_load to be used in bth_add area
Because i am trying to get the ID when it has been clicked from another form to frmAddFollowUp so i tried to request it from the page_load as when i request from the add button, it only gives me the number 0 instead of the id from the previous form.
Partial Class frmAddFollowUp
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim objCDBFeedback As New CDBFeedback
Dim objCDBDepartment As New CDBDepartment
Dim intGuestID1 As Integer
Dim arrList As New ArrayList
If Page.IsPostBack = False Then
intGuestID1 = Request.QueryString("id")
arrList = objCDBDepartment.getAllDepartmentDropDownList
lstDepartment.DataSource = arrList
lstDepartment.DataTextField = "DepartmentName"
lstDepartment.DataValueField = "Department"
lstDepartment.DataBind()
End If
End Sub
Protected Sub btnAdd_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAdd.Click
Dim CheckBoolean As Boolean = True
Dim objCDBFeedback As New CDBFeedback
Dim objCFeedback As New CFeedback
If txtStaffName.Text = "" Then
lblValidateStaffName.Text = "*Please enter Staff Name."
CheckBoolean = False
Else
lblValidateStaffName.Text = ""
End If
If txtFollowUpSummary.Text = "" Then
lblValidateFollowUpSummary.Text = "*Please enter Follow up summary."
CheckBoolean = False
ElseIf txtFollowUpSummary.Text.Contains("'") Then
txtFollowUpSummary.Text = txtFollowUpSummary.Text.Replace("'", "''")
Else
lblValidateFollowUpSummary.Text = ""
End If
If txtAmount2.Text = "" Then
lblValidateAmount2.Text = "*Please enter the Amount or put in NIL if there is no amount."
CheckBoolean = False
Else
lblValidateAmount2.Text = ""
End If
If CheckBoolean = False Then
If txtStaffName.Text.Contains("''") Then
txtStaffName.Text = txtStaffName.Text.Replace("''", "'")
End If
If txtFollowUpSummary.Text.Contains("''") Then
txtFollowUpSummary.Text = txtFollowUpSummary.Text.Replace("''", "'")
End If
Else
Dim intNumOfRecordsAffected As Integer
objCFeedback.GuestId = intGuestID1
objCFeedback.Feedback = txtFollowUpSummary.Text
objCFeedback.Department = lstDepartment.SelectedItem.Value
objCFeedback.StaffName = txtStaffName.Text
objCFeedback.Amount = txtAmount2.Text
intNumOfRecordsAffected = objCDBFeedback.addNewFollowUp(objCFeedback)
Response.Redirect("frmIncident.aspx")
End If
End Sub

You may either specify ByRef parameter type or use Function that returns reference of an object. In your code-snippet, you may declare variable at class-level (fields) so you may use them in different event handlers/sub.

Make intGuestID1 a private member variable. That will allow you to access this variable in both functions.
Is this code compiling? I do not see intGuestID1 being declared in btnAdd_Click, this should be throwing an error.
To declare a private member variable add the following above the Page_Load function, for example:
Partial Class frmAddFollowUp
Inherits System.Web.UI.Page
Private _intGuestID1 as Integer ' The _ prefix is just a naming convention that is used for class member variables, if you don't like it, you can remove it.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Now, in your Page_Load method, remove the line Dim intGuestID1 As Integer, as you no longer need to declare this. Finally, anywhere you see intGuestID1, rename it to _intGuestID1
Also, some ways to possibly refactor this is to create a Read Only Property that encapsulates the fact that you're getting _intGuestID1 from the QueryString. See the following example:
Private ReadOnly Property GuestID1() as Int32
Get
Return Request.QueryString("id")
End Get
End Property
One of the benefits of doing this is to perform any checks on the value before using it, such as, is it an actual number that is stored in Request.QueryString("id"), or is the user allowed to have access to the entity represented by this id, or whatever else you can think of. When you do this, you'll need to change all references to _intGuestID1 to GuestID1.

Related

VB.net ref value seem to not work

I'm passing a value by reference in this code
Private Sub login()
Dim login As New login(lListClients, bConnected)
login.ShowDialog()
login.Dispose()
If (bConnected = True) Then
Console.WriteLine("Mokmeuh")
Button3.Visible = True
Button4.Visible = True
Button7.Visible = True
End If
End Sub
And this is the login form
Public Class login
Private lListClients As List(Of Client)
Private bConnected As Boolean
Sub New(ByRef lListClients As List(Of Client), ByRef bConnected As Boolean)
InitializeComponent()
Me.lListClients = lListClients
Me.bConnected = bConnected
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim sID = TextBox1.Text, sPassword As String = TextBox2.Text
For Each cClient As Client In lListClients
If (Equals(cClient.getID, sID)) Then
If (Equals(cClient.getPassword, sPassword)) Then
bConnected = True
MessageBox.Show("Vous ĂȘtes connectĂ© vous pouvez continuez")
Me.Close()
End If
Else
MessageBox.Show("Votre ID n'existe pas")
TextBox1.Clear()
TextBox2.Clear()
TextBox1.Focus()
End If
Next
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
For Each m As Object In Me.Controls
If TypeOf m Is TextBox Then
CType(m, TextBox).Text = Nothing
End If
Next
Me.Close()
End Sub
Private Sub login_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TextBox1.Select()
End Sub
End Class
Whenever I launch it the bConnected value in form 1 is always false but in the login form it's true upon destruction so I'm really confuse here I've passed the value by reference it should, when set as true in the login.vb, be true as well in the form1.vb but thw condition If (bConnected = True) is never true.
So I need some help thank you
BTW : Sorry for my bad english
Although you can pass parameters by reference, you cannot store these references. If you want to change the parameter's value, you have to do it in the called method. Otherwise, the runtime cannot ensure that the variable is still alive.
A List(Of T) is already a reference type. So it is usually not reasonable to pass this parameter by reference. The variable lListClients holds a reference to the actual list object. When passing the variable by value, this reference is copied and passed to the method, resulting in another reference to the very same object. The only reason why you would want to pass this by reference is to change the variable's value from the called method, i.e. assign a new list.
The solution for your problem is quite simple. Create a public property:
Public Class login
Public Property Connected As Boolean
'...
Connected = True
'...
End Class
And use the login object to check the value:
If login.Connected Then
Of course, you should not dispose of the object until you check the value.

Retrieve a object from a list of objects in visual basic and use it to fill text/combo boxes

I have a class as seen below:
Public Class parameters
Public Property test As String
Public Property test_type As String
Public Property user_test_name As String
Public Property meas As String
Public Property spec As String
...etc
End Class
I make a list of objects that I import from a csv somewhere. The user_test_name's from the list gets sent to a list box:
For Each parameters In param
' MsgBox(parameters.user_test_name)
ListBox1.Items.Add(parameters.user_test_name)
Next
now when the user selects something from the list i want the rest of the properties of that particular user_test_name object to populate in certain text/combo boxes in the application. Here is how I grab what is selected.
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Dim selected_name As String = ListBox1.SelectedItem()
' MsgBox(selected_name)
find_object_by_user_test_name(selected_name)
End Sub
Now i'm having difficulty finding the object with the selected_name from the list and using its properties to fill the text.combo boxes. I tried the following to no success:
Public Sub find_object_by_user_test_name(ByVal description)
MsgBox(description)
Dim matches = From parameters In param
Where parameters.user_test_name = description
Select parameters
' MsgBox(matches)
' MsgBox(matches.user_test_name)
TextBox1.Text = matches.test
TextBox2.Text = matches.test_name
etc,,, on and on
' populate_area(matches)
End Sub
Instead of adding the name (a string) to the ListBox, add your actual INSTANCE to it.
First, override ToString() in your class so that it displays properly in your ListBox:
Public Class parameters
Public Property test As String
Public Property test_type As String
Public Property user_test_name As String
Public Property meas As String
Public Property spec As String
Public Overrides Function ToString() As String
Return user_test_name
End Function
End Class
Next, add each instance to the ListBox:
For Each parameters In param
ListBox1.Items.Add(parameters)
Next
Now, the SelectedIndexChanged() event, you can cast the SelectedItem() item back to parameters and you already have everything at your disposal:
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
If ListBox1.SelectedIndex <> -1 Then
Dim P As parameters = DirectCast(ListBox1.SelectedItem, parameters)
' ... do something with "P" ...
Debug.Print(P.user_test_name & " --> " & P.test)
End If
End Sub
If the user_test_names are unique, it may be easier to use a dictionary and retrieve the objects that way.
Dim params As New Dictionary(Of String, parameters)
params.add(MyParameterObject.user_test_name, MyParameterObject)
Then
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Dim selected_name As String = ListBox1.SelectedItem()
Dim selected_param as parameters = params(selected_name)
End Sub
Something like this should do it:
Public Sub find_object_by_user_test_name(ByVal description As String)
' assuming param is your list of parameter objects
For Each p In param
If p.user_test_name = description Then
TextBox1.Text = p.test
TestBox2.Text = p.test_name
...
Exit For
End If
Next
End Sub
A few notes about your code. First, you can't allow two objects to have the same user_test_name. Second, you can't use parameters as a variable name if you already have a class called parameters in your current namespace (which you do).
There is a simpler solution than any of these--just do the following:
Dim i as Integer = ListBox1.SelectedIndex
Then you can use i as an index to your original list of objects.

Moving single member of an Object in List into an array for usew in a calculation

I have a List of objects(Appliance as String and KwHHr as Double), applianceListReturn , in Visual Basic 2010. Each object has two members. I would like to take one member(KwHHr) of the same type from each object and make an array out of those single members. I am new to VB and this is not as easy as it first appeared. I have attempted to use a `for each loop to achieve this but it only returns one value. This is my code:
Imports System.Collections.Generic
Public Class Form1
Private ApplName As String '= Nothing
Private ApplKwCost As Double
Dim ConvAppliance As String
Dim ConvKwHHr As String
Public KwhCost As Double = 0
Dim ApplianceCost As New ArrayList()
'create structure for object in list
Private Structure Appliance
'public Variables
Public Appliance As String
Public KwHHr As Double
' provide get methods to allow return of objects in a formatted way
Public ReadOnly Property ApplianceInfo() As String
Get
Return Appliance & " " & KwHHr
End Get
End Property
Public ReadOnly Property ApplianceInfo2() As String
Get
Return Appliance & " " & KwHHr
Return KwHHr
End Get
End Property
Public Overrides Function ToString() As String
Return ApplianceInfo2
End Function
End Structure
Private ApplianceObj As Appliance
Dim arraylistReturn As New List(Of Appliance)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' choose KwHr price
KwCost.Text = KwhCost
' add appliance data to list
ApplianceObj.Appliance = "Washer"
ApplianceObj.KwHHr = 1.25
arraylistReturn.Add(New Appliance With {.Appliance = ApplianceObj.Appliance, .KwHHr = ApplianceObj.KwHHr})
ApplianceObj.Appliance = "Dryer"
ApplianceObj.KwHHr = 1.3
arraylistReturn.Add(New Appliance With {.Appliance = ApplianceObj.Appliance, .KwHHr = ApplianceObj.KwHHr})
ApplianceObj.Appliance = "Toaster"
ApplianceObj.KwHHr = 1.54
arraylistReturn.Add(New Appliance With {.Appliance = ApplianceObj.Appliance, .KwHHr = ApplianceObj.KwHHr})
End Sub
Private Sub ApplAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ApplAdd.Click
KwhCost = KwCost.Text
Dim newArray() As Double = {1.25, 1.3, 1.54}
'enter appliance data
ApplianceObj.Appliance = TxtBxApplAd.Text
ApplianceObj.KwHHr = TextBoxKwhUse.Text
ApplianceCost.Add(ApplianceObj.KwHHr)
'displays added appliances in applist listbox
displayAppliance(ApplianceObj)
'add applianceobj entries to arraylistreturn
arraylistReturn.Add(New Appliance With {.Appliance = ApplianceObj.Appliance, .KwHHr = ApplianceObj.KwHHr})
For Each App As Appliance In arraylistReturn
ArrayDispBox.Items.Add(App.ApplianceInfo.ToString())
Next
ReDim Preserve newArray(arraylistReturn.Count())
'count items in list
'AppList.Items.Add(arraylistReturn.Count().ToString)
newArray(arraylistReturn.Count()) = TextBoxKwhUse.Text
Dim sum As Double = 0
For int As Integer = 0 To newArray.GetUpperBound(0)
sum += newArray(int)
TextBoxTotal.Text = sum.ToString()
Next int
End Sub
Private Sub displayAppliance(ByVal App As Appliance)
AppList.Items.Add(App.ApplianceInfo2)
End Sub
' get selected appliances for calculation
Private Sub ArrayDispBox_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ArrayDispBox.SelectedIndexChanged
AppList.Items.Add(arraylistReturn.Item(ArrayDispBox.SelectedIndex))
End Sub
End Class
I hope this makes sense. Thank you for your help.
You can use LINQ to Object to achieve that:
Dim results As Array(Of String) = applianceListReturn.Select(Function(a) a.KwHHr).ToArray()

Using Generic List(Of Form), Trouble gathering Object's Name Property

I have been very interested as of late in interfaces and the ability to further customize them beyond using them in their default state.
I have been researching IList(of T) specifically. The advantages of using generic lists as opposed to ArrayLists has astounded me. Here is a picture of a test. This is the site that goes into further explanation about the Test.
So, naturally I wanted to experiment. When I first iterate through the list with the ForNext method the code works fine. The second time I can't access the name of the Form in the list because it is disposed. Anyone have any insight how I can access the forms properties in the list.
Public Class frmMain
Dim Cabinet As List(Of Form) = New List(Of Form)
Dim FormA As New Form1
Dim FormB As New Form2
Dim FormC As New Form3
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles _Me.Load
Cabinet.Add(FormA)
Cabinet.Add(FormB)
Cabinet.Add(FormC)
End Sub
Sub displayForm(ByVal aForm As Form)
Dim myFormName As String = ""
Stopwatch.Start()
If aForm.IsDisposed = False Then
aForm.Show()
Else
myFormName = aForm.(How do I access this objects Name?)
aForm = New Form '<----- I would rather simply use aForm = New(aForm)
aForm.Name = myFormName
aForm.Show()
End If
Stopwatch.Stop()
Dim RealResult As Decimal = (Stopwatch.ElapsedMilliseconds / 1000)
Debug.WriteLine(RealResult)
Stopwatch.Reset()
End Sub
Private Sub btnForEach_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnForEach.Click
'Dim instance as List
'Dim action as Action(of T)
'instance.ForEach(action)
'action = delegate to a method that performs an action on the object passeed to it
Cabinet.ForEach(AddressOf displayForm)
End Sub
I really don't understand why if VB knows that this is a Generic list, which means it is knowledgable of the list's type, and the objects are all constrained to be forms; why I can't call a constructor on an item in the list. Ex. aForm = New aForm or aForm = New Cabinet.aForm
Tear this one open for me somebody. Thanks.
You can't construct a new instance of "aForm" because its isn't a type, it is an instance of type Form.
If you wanted to prevent the ObjectDisposedException, you could hide the form instead of closing it. Place the following code in each forms code behind:
Public Class Form1
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
Dim form = CType(sender, Form)
form.Visible = False
e.Cancel = True
End Sub
End Class
This is a bit hacky, however, but then you wouldn't need the code in the Else block.
Edit
You could try this instead:
Private Sub displayForm(ByVal aForm As Form)
Dim indexOfCab As Integer = Cabinet.IndexOf(aForm)
If indexOfCab <> -1 Then
If aForm.IsDisposed Then
aForm = CreateForm(aForm.GetType())
Cabinet(indexOfCab) = aForm
End If
aForm.Show()
End If
End Sub
Private Shared Function CreateForm(formType As Type) As Form
Return CType(Activator.CreateInstance(formType), Form)
End Function
You wouldn't need that big Select statement.
This is the only way I have been able to get it to work. I feel it is extremely inefficient however, and hope someone can set me on a path to a better way to do this. The below is what I'm trying to achieve.
Sub displayForm(ByVal aForm As Form)
Dim myFormName As String = ""
If Cabinet.Contains(aForm) Then
Dim indexOfCab As Integer = Cabinet.IndexOf(aForm)
Dim ObjForm As Form = Cabinet.Item(indexOfCab)
If aForm.IsDisposed Then
Select Case indexOfCab
Case 0
aForm = Nothing
aForm = New Form1
Cabinet.Item(indexOfCab) = aForm
Cabinet.Item(indexOfCab).Show()
Case 1
aForm = Nothing
aForm = New Form2
Cabinet.Item(indexOfCab) = aForm
aForm.Show()
Case 2
aForm = Nothing
aForm = New Form3
Cabinet.Item(indexOfCab) = aForm
Cabinet.Item(indexOfCab).Show()
End Select
Else
Cabinet.Item(indexOfCab).Show()
End If
End If
End Sub

VB.NET - Created Class, Working with WriteOnly property but its not replacing variable value

After program execution, the extension that the FileStream uses is the default one provided in the Class header instead of the one i specified via the "set property".
How come it never changed?
Form1.vb Code
Option Strict On
Imports S3_BalanceBook_Dayan.Wallet
Public Class Form1
Dim myWallet As New Wallet(DataGridView1, DateTimePicker1)
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Make default selection when program starts.
optCheck.Checked = True
myWallet.StatementsFileName = "statements.dat"
DataGridView1.Rows.Add(New String() {"12/21/1986", "Test", "44554", "44.22", "45.12"})
End Sub
Private Sub cmdAddTransaction_Click(sender As System.Object, e As System.EventArgs) Handles cmdAddTransaction.Click
If optCheck.Checked Then
lblAvailableFunds.Text = FormatCurrency(myWallet.Check(CInt(Trim(txtCheck.Text)), _
CDec(Trim(txtMoney.Text))))
End If
End Sub
Private Sub optDeposit_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles optDeposit.CheckedChanged
'Disable un-needed fields when Deposit Radio button is selected!
txtCheck.Enabled = False
txtMoney.Enabled = False
txtDeposit.Enabled = True
txtFee.Enabled = False
txtDescription.Enabled = True
End Sub
Private Sub optCheck_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles optCheck.CheckedChanged
'Disable un-needed fields when Check Radio button is selected!
txtCheck.Enabled = True
txtMoney.Enabled = True
txtDeposit.Enabled = False
txtFee.Enabled = False
txtDescription.Enabled = True
End Sub
Private Sub optServiceFee_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles optServiceFee.CheckedChanged
'Disable un-needed fields when Fee Radio button is selected!
txtCheck.Enabled = False
txtMoney.Enabled = False
txtDeposit.Enabled = False
txtFee.Enabled = True
txtDescription.Enabled = True
End Sub
End Class
Wallet.vb Code
Option Strict On
Imports System
Imports System.IO
Public Class Wallet
Private lcheckNumber As Integer = Nothing
Private lcheckmoney As Decimal = Nothing
Private ldepositAmount As Decimal = Nothing
Private lfee As Decimal = Nothing
Private holdInstance As DataGridView
Private holdDate As DateTimePicker
Private holdPath As String = "default.txt"
Private _file As New FileStream(holdPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
Private file As New StreamWriter(_file)
'Default Constructor
Public Sub New()
End Sub
Public Sub New(ByRef Data As DataGridView, ByRef StatementDate As DateTimePicker)
'This constructor takes in references to use in class as private
holdInstance = Data
holdDate = StatementDate
End Sub
''' <summary>
''' Property allows the change of file path for the statements log.
''' </summary>
Public WriteOnly Property StatementsFileName() As String
Set(ByVal Value As String)
holdPath = Value
End Set
End Property
''' <summary>
''' Enter Deposit amount as Decimal, returns remainding account balance as Decimal.
''' </summary>
Public Function Deposit(ByVal Amount As Decimal) As Decimal
Return 0D
End Function
'Function Check - Deduct the amount and returns current balance.
Public Function Check(ByVal CheckNumber As Integer, ByVal CheckAmount As Decimal) As Decimal
Try
file.WriteLine(CheckNumber & " - " & CheckAmount)
Catch e As IOException
MessageBox.Show(e.ToString)
End Try
Return 0D
End Function
'Function Fee - Deduct the fee from balance and returns current balance.
Public Function Fee(ByVal FeeAmount As Decimal) As Decimal
Return 0D
End Function
End Class
Yup - it's here that the problem is:
Private holdPath As String = "default.txt"
Private _file As New FileStream(holdPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
Private file As New StreamWriter(_file)
That will initialize _file with the value of holdPath, at the point at which the Wallet instance is created. Instead of having _file and file as member fields, why not make them local variables inside Check? That way, when they're constructed, they'll use the value of holdPath, as it is at that time.
You should also, probably, put them inside Using statements, or otherwise ensure that they're closed at a suitable point - otherwise, the contents you write to the file may not appear until your program is closed.
So, we'd have:
Public Function Check(ByVal CheckNumber As Integer, ByVal CheckAmount As Decimal) As Decimal
Try
Using _file As New FileStream(holdPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
Using file As New StreamWriter(_file)
file.WriteLine(CheckNumber & " - " & CheckAmount)
End Using
End Using
Catch e As IOException
MessageBox.Show(e.ToString)
End Try
Return 0D
End Function