Login Screen: Stack overflow exception - vb.net

I am studying VB.NET so I want to make a simple login screen. For now, I only want that if I click on the button it writes something to the console ( I still dont know where that output is going ) but I get a stack overflow exception as soon as I click in Run.
Can someone advice me in why this code does not work?
Public Class Form1
Private Class Users
Public Property Name() As String
Get
' Gets the property value.
Return Name
End Get
Set(ByVal Value As String)
' Sets the property value.
Name = Value
End Set
End Property
Public Property Password() As String
Get
' Gets the property value.
Return Password
End Get
Set(ByVal Value As String)
' Sets the property value.
Password = Value
End Set
End Property
Public Sub New(ByVal name As String, ByVal password As String)
Me.Name = name
Me.Password = password
End Sub
End Class
Private user As New Users("Matias", "Barrios")
Private Sub Label1_Click(sender As Object, e As EventArgs) Handles Label1.Click
End Sub
Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Public Sub Validar(nombre As String, password As String)
Me.TextBox1.Text = user.Name
If nombre = user.Name And password = user.Password Then
System.Console.Write(user.Name)
Me.TextBox1.Text = "No"
End If
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Validar("Matias", "Barrios")
System.Console.Write("Click!")
End Sub
End Class

You have this:
Public Property Name() As String
Get
' Gets the property value.
Return Name
End Get
Set(ByVal Value As String)
' Sets the property value.
Name = Value
End Set
End Property
The Get for that property refers to itself. So Get calls Get, which calls Get again, and so on, forever, until you run out of stack space for the function calls. Set does the same thing.
To fix the problem, the property is simple enough to use the auto-implement shorthand:
Public Property Name As String
But if you want to do it the long way, you need a backing field with a different name:
Private _Name As String
Public Property Name() As String
Get
' Gets the property value.
Return _Name
End Get
Set(ByVal Value As String)
' Sets the property value.
_Name = Value
End Set
End Property
Whichever you choose, you'll need to make the same change for the Password property.

Related

What should I add to a custom class so it works with System.Windows.Forms.Listbox.Items.Contains()..?

What should I add to a custom class so it works with System.Windows.Forms.Listbox.Items.Contains()..?
I've created a class called "FileItem" for handling filenames in ListBoxes. It works as expected, but if I try to use ListBox.Items.Contains() to prevent duplicate items from being added, nothing happens. The Contains() function never returns True.
Here's the code. Add it to a VB.Net form named frmTest with a ListBox1, Button1, and Button2. Run it and press Button1 multiple times. The duplicate warning message is never displayed.
Public Class frmTest
Private Sub frmTest_Load(sender As Object, e As EventArgs) Handles Me.Load
With ListBox1
.DisplayMember = "ShortName"
.ValueMember = "LongName"
End With
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim f As FileItem = New FileItem("C:\Windows\Notepad.exe")
If ListBox1.Items.Contains(f) Then
MsgBox("The file is already added and will be skipped.")
Else
ListBox1.Items.Add(f)
End If
f = Nothing
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim msg As String = ""
For Each item As FileItem In ListBox1.Items
msg &= item.FullName & vbCr
Next
MsgBox(msg)
End Sub
Private Class FileItem
Private ReadOnly _FullName As String
Private ReadOnly _ShortName As String
Public Sub New(ByVal FullName As String)
_FullName = FullName
If FullName.Contains("\") Then
Dim pos As Integer = FullName.LastIndexOf("\")
_ShortName = FullName.Substring(pos + 1)
End If
End Sub
Public ReadOnly Property FullName() As String
Get
Return _FullName
End Get
End Property
Public ReadOnly Property ShortName() As String
Get
Return _ShortName
End Get
End Property
Public Overrides Function ToString() As String
Return _FullName
End Function
End Class
End Class

How to associate an object with ToolStripMenuItem VB.net?

Public Class Apple
Private d_isplayName As String
Public Property DisplayName() As String
Get
Return d_isplayName
End Get
Set(ByVal value As String)
d_isplayName = value
End Set
End Property
Private u_niqueVal As String
Public Property uniqueVal() As String
Get
Return u_niqueVal
End Get
Set(ByVal value As String)
u_niqueVal = value
End Set
End Property
End Class
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim RedApple As New Apple With {.DisplayName = "redapple", .uniqueVal = "Uval"}
tsiAddFruit.DropDownItems.Add("Some Text", Nothing, AddressOf fruit_Click)' Work fine
tsiAddFruit.DropDownItems.Add(RedApple, Nothing, AddressOf fruit_Click)' does not work
End Sub
Private Sub fruit_Click(sender As System.Object, e As System.EventArgs)
Dim MenuItem As ToolStripMenuItem = DirectCast(sender, ToolStripMenuItem)
MessageBox.Show(MenuItem.Text)
End Sub
How can I pass an object in ToolStripMenuItem without using the .Tag property(no third-party tool too)? I want to use Apple.DisplayName and the display value and Apple.UniqueVal as the value type.

Entering data into a datagrid

I am using Visual Basic 2008. I am trying to enter 2 columns of text into a datagrid using a button.
When i press the button a variable and a data associated to the variable should be entered into 2 columns of datagrid.
The code i am using is:
Public Class Entering_the_rates
Public Class Datagrid
Private category As String
Public Property getcategory() As String
Get
Return category
End Get
Set(ByVal value As String)
category = value
End Set
End Property
Private price As Decimal
Public Property getprice() As Decimal
Get
Return price
End Get
Set(ByVal value As Decimal)
price = value
End Set
End Property
End Class
Private Sub Entering_the_rates_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
datagridadult() as new Datagrid (category, price)
End Sub
End Class
is this syntax right or wrong.
I also need a sample code on how to call a datagrid i have declared . Please help me
You need a constructor in your class:
Public Class Datagrid
Private _category As String
Public Property getcategory() As String
Get
Return category
End Get
Set(ByVal value As String)
category = value
End Set
End Property
Private _price As Decimal
Public Property getprice() As Decimal
Get
Return price
End Get
Set(ByVal value As Decimal)
price = value
End Set
End Property
Public Sub New(byval category as string, byval price as decimal)
_category = category
_price = price
End Sub
End Class
Your private variables behind your properties should start with an underscore too, see here: http://10rem.net/articles/net-naming-conventions-and-programming-standards---best-practices this makes assigning them in the constructor easier. You could also use autoimplemented properties, these auto create the _ behind variables for you (though they do not show in intellisense).

VB.NET: Fields from a class

I have a class being populated from comma separated rows in a text file.
I am trying to have the name property of each object appear in a listbox, then have the rest of the properties of a selected object show up in text boxes. How do I load the properties of the selected object to the correct textbox?
I'm assuming that the class you fill has a list of the objects and that you have already figured out how to fill the listbox...
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
For Each obj As YourObjectType In YourClass.CollectionOfYourObjects
If obj.Name = ListBox1.SelectedItem.ToString Then
Textbox1.Text = obj.Property1
Textbox2.Text = obj.Property2
End If
Next
End Sub
You have one TextBox for every Property and the number of properties is static, isn't it?
You have to set the DisplayMember to the Property's name that you want to see in the Listbox.
This simplified sample should work:
Public Class ListBox
Private Sub ListBox_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim allFoos As New List(Of FooClass)
For i As Int32 = 1 To 10
Dim foo As New FooClass
foo.Name = "Foo_" & i
foo.Prop1 = "Prop1_" & i
foo.Prop2 = "Prop2_" & i
foo.Prop3 = "Prop3_" & i
allFoos.Add(foo)
Next
Me.ListBox1.DataSource = allFoos
Me.ListBox1.DisplayMember = "Name"
End Sub
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Dim foo As FooClass = DirectCast(ListBox1.SelectedItem, FooClass)
Me.TxtName.Text = foo.Name
Me.TxtProp1.Text = foo.Prop1.ToString
Me.TxtProp2.Text = foo.Prop2.ToString
Me.TxtProp3.Text = foo.Prop3.ToString
End Sub
End Class
Class FooClass
Private _name As String
Private _prop1 As Object
Private _prop2 As Object
Private _prop3 As Object
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
End Set
End Property
Public Property Prop1() As Object
Get
Return _prop1
End Get
Set(ByVal value As Object)
_prop1 = value
End Set
End Property
Public Property Prop2() As Object
Get
Return _prop2
End Get
Set(ByVal value As Object)
_prop2 = value
End Set
End Property
Public Property Prop3() As Object
Get
Return _prop3
End Get
Set(ByVal value As Object)
_prop3 = value
End Set
End Property
End Class

List Boxes in VB.NET

I want to manually add two items as "Active" and "Inactive" in a ListBox. When the user selects "Active", i want to get the value "A" and when "Inactive" is selected, i want to get "I".
How do i do this in VB.NET.
Are you using .NET 4? If so, the simplest solution is probably to use Tuple(Of String, String). Create a tuple of ("Active", "A") and another of ("Inactive", "I") and add those to the listbox. Then set the listbox's DisplayMember property to "Item1" and ValueMember to "Item2".
Or you could do the same sort of thing with an anonymous type.
The ListboxItemCollection is of type Object. You can create a custom ListItem like this
Public Class Form1
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
BindListBox()
End Sub
Private Sub BindListBox()
With ListBox1
.Items.Add(New CustomListItem("Acitve", "A"))
.Items.Add(New CustomListItem("Inactive", "I"))
.DisplayMember = "Text"
End With
End Sub
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
MsgBox(CType(ListBox1.SelectedItem, CustomListItem).Value)
End Sub
End Class
''Custom ListItem Class
Public Class CustomListItem
Dim _text As String
Dim _value As String
Sub New(ByVal text As String, ByVal value As String)
Me._text = text
Me._value = value
End Sub
Public ReadOnly Property Text() As String
Get
Return _text
End Get
End Property
Public ReadOnly Property Value() As String
Get
Return _value
End Get
End Property
End Class
A simple option
Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
Debug.Print(ListBox1.Items(ListBox1.SelectedIndex).ToString.Substring(0, 1))
End Sub