Overview

This article is intended to show two programming lessons for beginner programmers. 

First, it shows how to combine object arrays, simple user-defined object classes, properties, and simple code, to create OOP (Object Oriented Programming) applications with Visual Studio. 

Secondly, it shows how to use simple LINQ queries with Lambda functions, to quickly search a user-defined object array.

Arrays in VS can be arrays of primitive types (Integer, Byte, Boolean etc.), but it's possible to create an array of just about any type you can imagine. A user-defined class typically contains Properties and Public or sometimes Private Methods. In the case of the example programs there are two user-defined classes - ElementDetails, which contains (from each element) the AtomicNumber, the Symbol, the Element (name), the [Type] (the Element's group), and finally the Image Property, which actually returns a dynamic Bitmap created on the fly in the Property Getter. The [Type] Property could have been a String representing the name of the group, but it was advantageous to store two Properties related to the Group - the name, and a color. So, the return type of the Type Property is ElementType, which is the second of the core classes used.

LINQ combined with Lambda gives great results from minimal code. It is possible to query the user-defined array on any of the Properties to retrieve either one element or a group of elements.







The searchForm code

Public Class searchForm
 
    Dim types() As ElementType =
            {New ElementType("Alkali metal", 255, 101, 101),
            New ElementType("Alkaline earth metal", 255, 222, 174),
            New ElementType("Lanthanide", 255, 188, 253),
            New ElementType("Actinide", 255, 150, 201),
            New ElementType("Transition metal", 255, 190, 191),
            New ElementType("Post-transition metal", 203, 203, 203),
            New ElementType("Metalloid", 203, 204, 154),
            New ElementType("Polyatomic nonmetal", 159, 255, 196),
            New ElementType("Diatomic nonmetal", 230, 255, 148),
            New ElementType("Noble gas", 190, 255, 255),
            New ElementType("Unknown chemical properties", 231, 231, 231)}
 
    Dim elements(117) As ElementDetails
 
    Dim ignore As Boolean = False
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim lines() As String = My.Resources.elements.Split(New String() {Environment.NewLine}, StringSplitOptions.None)
        For x As Integer = 0 To 117
            elements(x) = New ElementDetails(types, lines(x).Split("|"c))
        Next
    End Sub
 
    Private Sub updateFields(ByVal exclude As Integer, current As ElementDetails)
        If ignore Then Return
        ignore = True
        Select Case exclude
            Case 0
                If current IsNot Nothing Then
                    TextBox1.Text = current.Symbol
                    TextBox2.Text = current.Element
                    Button1.BackColor = current.Type.Color
                    Button1.Text = current.Type.Name
                Else
                    clearFields(exclude)
                End If
            Case 1
                If current IsNot Nothing Then
                    NumericUpDown1.Value = current.AtomicNumber
                    TextBox2.Text = current.Element
                    Button1.BackColor = current.Type.Color
                    Button1.Text = current.Type.Name
                Else
                    clearFields(exclude)
                End If
            Case 2
                If current IsNot Nothing Then
                    NumericUpDown1.Value = current.AtomicNumber
                    TextBox1.Text = current.Symbol
                    Button1.BackColor = current.Type.Color
                    Button1.Text = current.Type.Name
                Else
                    clearFields(exclude)
                End If
        End Select
        ignore = False
    End Sub
 
    Private Sub clearFields(ByVal exclude As Integer)
        ignore = True
        Select Case exclude
            Case 0
                NumericUpDown1.Value = 0
                TextBox2.Text = ""
                Button1.BackColor = SystemColors.Control
                Button1.Text = ""
            Case 1
                NumericUpDown1.Value = 0
                TextBox2.Text = ""
                Button1.BackColor = SystemColors.Control
                Button1.Text = ""
            Case 2
                NumericUpDown1.Value = 0
                TextBox1.Text = ""
                Button1.BackColor = SystemColors.Control
                Button1.Text = ""
        End Select
        ignore = False
    End Sub
 
    Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged, NumericUpDown1.TextChanged
        updateFields(0, elements.FirstOrDefault(Function(el) el.AtomicNumber = CInt(NumericUpDown1.Value)))
    End Sub
 
    Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
        updateFields(1, elements.FirstOrDefault(Function(el) el.Symbol = TextBox1.Text))
    End Sub
 
    Private Sub TextBox2_TextChanged(sender As Object, e As EventArgs) Handles TextBox2.TextChanged
        updateFields(2, elements.FirstOrDefault(Function(el) el.Element = TextBox2.Text))
    End Sub
 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Button1.Text <> "" Then
            Dim frm As New listForm(Button1.Text, elements.Where(Function(el) el.Type.Name = Button1.Text).ToArray)
            frm.ShowDialog()
        End If
    End Sub
 
End Class




The ElementDetails Class code

'''
''' <summary>
''' @author Paul Long
''' </summary>
Public Class ElementDetails
 
    Private _atomicNumber As Integer
    Private _symbol As String
    Private _element As String
    Private _type As ElementType
 
    ''' <returns> the atomicNumber </returns>
    Public ReadOnly Property AtomicNumber As Integer
        Get
            Return Me._atomicNumber
        End Get
    End Property
 
    ''' <returns> the symbol </returns>
    Public ReadOnly Property Symbol As String
        Get
            Return Me._symbol
        End Get
    End Property
 
    ''' <returns> the element </returns>
    Public ReadOnly Property Element As String
        Get
            Return Me._element
        End Get
    End Property
 
    ''' <returns> the type </returns>
    Public ReadOnly Property [Type] As ElementType
        Get
            Return Me._type
        End Get
    End Property
 
    Public ReadOnly Property Image As Bitmap
        Get
            Dim img As New Bitmap(120, 80)
            Dim g As Graphics = Graphics.FromImage(img)
 
            g.Clear(Me.Type.Color)
            g.DrawRectangle(Pens.Black, 0, 0, 119, 79)
 
            Dim sf As New StringFormat
            sf.Alignment = StringAlignment.Center
            sf.LineAlignment = StringAlignment.Center
 
            g.DrawString(Me.AtomicNumber.ToString(), New Font(searchForm.Font.FontFamily, 12, FontStyle.Bold), Brushes.Black, New Rectangle(0, 0, 120, 25), sf)
            g.DrawString(Me.Symbol, New Font(searchForm.Font.FontFamily, 12, FontStyle.Bold), Brushes.Black, New Rectangle(0, 27, 120, 25), sf)
            g.DrawString(Me.Element, searchForm.Font, Brushes.Black, New Rectangle(0, 52, 120, 25), sf)
 
            Return img
        End Get
    End Property
 
    Public Sub New(ByVal elementTypes() As ElementType, ParamArray ByVal fields() As String)
        Me._atomicNumber = CInt(fields(0).Trim())
        Me._symbol = fields(1).Trim()
        Me._element = fields(2).Trim()
        Me._type = elementTypes.Where(Function(x) fields(3).Trim().Equals(x.Name)).First()
    End Sub
 
End Class




Conclusion

This article teaches good programming practice through encapsulation, and composition, which are essential elements of good OOP Programming. Using Class objects, arrays and LINQ it's easy to create concise and effective programs in minutes, and your code will be readable industry standard code.




Other Resources

Download here... VB.Net / C#


See Also

C# version