VB.net ref value seem to not work - vb.net

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.

Related

Passing parameters between two forms in VB.Net

I currently have about 5 forms in my application. I'm building a 6th form - frmSummary however, I'd like to be able to access it from all forms. in frmSummary I am planning to add a DataGridView, where I'll be displaying data related to that form. I'm thinking that I should either create a global variable such as
dim FrmName as String
In each form I would have a cmdSummary button so that On click_event, I would do something like
frmName ="CustomerInfo"
Currently the way my application is set up is that I hve a mdiForm and within it, each form is a child so on opening new forms I do something like...
Private Sub cmdSummary_Click(sender As Object, e As EventArgs) Handles cmdSummary.Click
Dim NewMDIChild As New frmClientEligibilityReferral()
frmName = "CustomerInfo" --since this will be comeing from frmCustomerInfo
NewMDIChild.MdiParent = MDIform1
NewMDIChild.Show()
MDIForm1.Show()
End Sub
So I do something like that on opening my new form. My question is how can I pass the parameter to my form frmSummary....here's currently what I'm trying to accomplish....
Private Sub FrmSummary_Load(sender As Object, e As EventArgs) Handles Me.Load
Me.MdiParent = MDIForm1
InitializeComponent()
'Here I want to call a function to load the datagridView(with g_frmName)see below...
call LoadDataGrid(frmName)
End Sub
Is something like that a smart idea? Or should I/Can I directly call the function from the previous form?
Just trying to see if I'm on the right track, if not, how can i do it in a sound way?
If there is only one frmSummary, you could make it a singleton.
In frmSummary, put the following code:
Private Shared _instance As frmSummary
Private Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
End Sub
Public Shared Function GetInstance() As frmSummary
If _instance Is Nothing Then
_instance = New frmSummary()
End If
Return _instance
End Function
Public Sub PutDataInGrid(data As Object)
Me.DataGridView1.' put data in it
End Sub
And you would access it from other forms like this
Dim myFrmSummary = frmSummary.GetInstance()
myFrmSummary.PutDataInGrid(myData)
If I understand the question correctly....
You can just set the required parameters in the New declaration sub (Where InitializeComponent() is supposed to be). On your form, declare variables and set one to each of the parameter values, and set up your form this way..
An example might be;
Public Class frmSummary
Dim var1 as String = ""
Dim var2 as Boolean = True
Public Sub New(ByVal parameter1 as String, ByVal parameter2 As Boolean)
var1 = parameter1
var2 = parameter2
InitializeComponent()
End Sub
Private Sub frmSummary_Load(sender as Object, e As EventArgs) Handles MyBase.Load
If var1 = "This String" Then
If var2 = False Then
sql = "SELECT * FROM myTable"
' Rest of your code to get the DGV data
DataGridView1.DataSource = Dt
Else
End If
End If
End Sub
Again, I may have misunderstood the question, so apologies if that is the case.

change GroupControl visibility of opened usercontrol from the form vb.net

I have one 'UserControl' that opened inside form,
this usercontrol has a 'GroupControl'
how can I make this 'GroupControl' hidden or visible when user click on a button that beings on the form
using vb.net
In the user control:
Public Property GroupControlVisible() As Boolean
Get
Return Me.GroupControl1.Visible
End Get
Set(value As Boolean)
Me.GroupControl1.Visible = value
End Set
End Property
Try this :
In you UserControl add a procedure how set visibility to your GroupControl :
Public sub SetVisibility (V as boolean)
YourGroupControl.visible=v
End Sub
In your form
Public Class Form1
Dim uc As New MyUserControl
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Me.Controls.Add(uc)
uc.Dock()
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
uc.SetVisibility(False)
'NB :MyUserControl is name of your usercontrol
End Sub
End Class
To Simplify, you can use :
MyParentForm.UserControlName1.GroupControlName.Visible = False
or
CType(MyParentForm.Controls("UserControlName").Controls("GroupControlName"), _
GroupControl).Visible = False
But the best way is create a property which allows changing the Visible property of the GroupControl in UserControl Class like this :
Public Property GroupControlVisibility() As Boolean
Get
Return Me.GroupControlName.Visible
End Get
Set(value As Boolean)
Me.GroupControlName.Visible = value
End Set
End Property

Form data erased after Windows form is closed

I have a subsidiary form where I can enter data and then save it before closing the form and going back to using the main form.
When I re-open the subsidiary form, I cannot see the changes in the data that I had entered earlier.
Can anyone tell me where I'm wrong ?
MainForm.vb
Public Class Maincls
oTestObj as New Testcls
oTestObj.XYZ = "XYZ"
Private Sub SoftwareSettingsToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SoftwareSettingsToolStripMenuItem.Click
Testcls.tbXYZ.Text = oTestObj.m_XYZ
Testcls.Show()
End Sub
End Class
Form_Testcls.vb
Public Class Testcls
Structure Params
Dim m_XYZ as String
End Structure
Dim oParams as Params
Public Sub New ()
InitializeComponent()
End Sub
Private Sub btnOK_Click(sender As System.Object, e As System.EventArgs) Handles btnOK.Click
XYZ = tbXYZ.Text
Me.Hide()
End Sub
Public Property XYZ() As String
Get
Return Me.oparams.m_XYZ
End Get
Set(ByVal value As String)
Me.oparams.m_XYZ = value
End Set
End Property
End Class
I think in windows forms the work around for this is to create a static class and add properties according to your requirement. Then populate these static properties on closing of your form. Now you can use the value set in the static data members, unless otherwise you change them on any other event.
Edit: In vb.net the Static is actually NonInheritable

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

How do i get the object from one sub to the other sub

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.