Click here to Skip to main content
15,886,026 members
Articles / Programming Languages / Visual Basic

Linking Multiple Embedded Controls

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
17 Aug 2011CPOL15 min read 35.4K   572   6  
This article explores software architectural improvements for creating a library of controls deployed in Windows Forms, Wonderware InTouch, and WinCC.
Imports System.Timers
Namespace MyCorp
    Public Class DataAccessLayer
        Implements IGetDataAccessLayer
        Public Event SelectedFuranceChanged(ByVal FurnaceIndex As Integer) Implements IGetDataAccessLayer.SelectedFuranceChanged
        Public Event DataUpdated(ByVal FurnaceIndex As Integer) Implements IGetDataAccessLayer.DataUpdated

        'Check for socket updates every tenth of a second.
        'Checking each tenth, will result in actual updates only about
        'once every second or so because of the exchange of messages.
        Private UpdateTimer As New System.Timers.Timer(5000)

        Private Shared m_Furnace As New SortedList(Of Integer, BaseFurnace)
        Public ReadOnly Property GetFurnace(ByVal FurnaceIndex As Integer) As BaseFurnace Implements IGetDataAccessLayer.GetFurnace
            Get
                Return DataAccessLayer.m_Furnace(FurnaceIndex)
            End Get
        End Property

        Private Shared m_Singleton As DataAccessLayer = New DataAccessLayer
        Public Shared ReadOnly Property DefInstance() As DataAccessLayer
            Get
                Return m_Singleton
            End Get
        End Property

        Private Shared m_SelectedFurnaceIndex As Integer
        Public Property SelectedFurnaceIndex() As Integer Implements IGetDataAccessLayer.SelectedFurnaceIndex
            Get
                Return m_SelectedFurnaceIndex
            End Get
            Set(ByVal value As Integer)
                If m_SelectedFurnaceIndex <> value Then
                    m_SelectedFurnaceIndex = value
                    If SelectedFuranceChangedEvent IsNot Nothing Then
                        RaiseEvent SelectedFuranceChanged(m_SelectedFurnaceIndex)
                    End If
                End If
            End Set
        End Property

        'This, the default constructor, is marked private to ensure
        'that no copies are instantiated. This is intended to be a 
        'Singleton class, and the only way to ensure that is to make
        'sure that no other module can instantiate a new one without
        'going through DefInstance. 
        Private Sub New()
            MyBase.New()
            Me.UpdateTimer.AutoReset = True
            AddHandler UpdateTimer.Elapsed, AddressOf OnUpdateTimerElapsed
            Me.UpdateTimer.Enabled = True

            Dim newFurnace As New JobFurnace
            m_Furnace.Add(0, newFurnace)
            Dim myContents As New Dictionary(Of String, BasePiece)
            myContents("Piece1") = New JobPiece
            myContents("Piece1").IsothermTemperatures = New Double(,) {{240, 159, 240}, {240, 240, 229}, {240, 240, 239}}
            myContents("Piece2") = New JobPiece
            myContents("Piece2").IsothermTemperatures = New Double(,) {{1150, 240, 1150}, {1501, 240, 1501}, {1150, 240, 1150}}
            myContents("Piece3") = New JobPiece
            myContents("Piece3").IsothermTemperatures = New Double(,) {{1150, 501, 1150}, {1501, 501, 1501}, {1150, 1501, 1150}}
            myContents("Piece4") = New JobPiece
            myContents("Piece4").IsothermTemperatures = New Double(,) {{1501, 1501, 1501}, {1501, 1501, 1501}, {1501, 1501, 1501}}
            myContents("Piece5") = New JobPiece
            myContents("Piece5").IsothermTemperatures = New Double(,) {{1501, 1750, 1750}, {1501, 1501, 1750}, {1750, 1750, 1750}}
            m_Furnace(0).Contents = myContents
            m_Furnace(0).SelectedPieceID = "Piece1"

            newFurnace = New JobFurnace
            m_Furnace.Add(1, newFurnace)
            myContents = New Dictionary(Of String, BasePiece)
            myContents("Piece1") = New JobPiece
            myContents("Piece1").IsothermTemperatures = New Double(,) {{1501, 1501, 1501}, {1501, 1750, 1501}, {1501, 1501, 1501}}
            myContents("Piece2") = New JobPiece
            myContents("Piece2").IsothermTemperatures = New Double(,) {{1501, 1501, 1501}, {1501, 1501, 1501}, {1501, 1501, 1501}}
            myContents("Piece3") = New JobPiece
            myContents("Piece3").IsothermTemperatures = New Double(,) {{1150, 501, 1150}, {1501, 1501, 1501}, {1150, 1501, 1150}}
            myContents("Piece4") = New JobPiece
            myContents("Piece4").IsothermTemperatures = New Double(,) {{240, 1150, 240}, {1150, 1501, 1150}, {240, 1150, 240}}
            myContents("Piece5") = New JobPiece
            myContents("Piece5").IsothermTemperatures = New Double(,) {{159, 240, 136}, {240, 1150, 229}, {133, 239, 160}}
            m_Furnace(1).Contents = myContents
            m_Furnace(1).SelectedPieceID = "Piece4"

            Me.SelectedFurnaceIndex = 0
        End Sub

        'Elapsed events are raised on threadpool threads. Be sure
        'to handle all possible exceptions within the event handler
        'and to allow for reentrant execution of the handler. If this
        'behaviour is undesirable, assign the SynchronizingObject to a shared
        'DataAccessLayer object.
        Public Sub OnUpdateTimerElapsed(ByVal source As Object, ByVal e As ElapsedEventArgs)
            Try
                'Notice here that we're running a ten-second process.
                System.Threading.Thread.Sleep(10000)
                Static FurnaceIndex As Integer = 0
                'After the first 10 seconds, though, this will print every 5 seconds.
                'Do you understand why?
                Debug.WriteLine("Hello from UpdateTimer.")
                RaiseEvent DataUpdated(FurnaceIndex)
                FurnaceIndex = (FurnaceIndex + 1) Mod 2
            Catch ex As Exception
                Debug.Print(ex.Message)
            End Try
        End Sub
    End Class

    Public Module FactoryProvider
        Public Function GetDataProvider() As IGetDataAccessLayer
            Return DataAccessLayer.DefInstance
        End Function
    End Module

End Namespace

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) TenovaCore
United States United States
Rod currently works in The Burgh using .Net technologies to create Human-Machine Interfaces for steel-making furnaces. He has 7 years in the steel industry, and 12 years of experience working in the nuclear industry at Savannah River Site in Aiken, SC. He enjoys riding his Honda Goldwing through the winding Pennsylvania farmlands, and taking his Jeep offroad.

Comments and Discussions