Click here to Skip to main content
13,804,094 members
Rate this:
 
Please Sign up or sign in to vote.
Hi All. My application requires variables to be set and retrieved multiple times in different forms and subs. Instead of writing the code multiple times i was hoping to use a loop to loop through the variables and set them accordingly. This is what i have so far. I'm stuck with setting the variable based on its name (See below).
Dim VariableA As Integer
Dim VariableB As String
Dim VariableC As Boolean
Dim VariableD As Double
Dim VariableNames(3) As String
Dim VariableValues(3) As String

Private Sub SetVariables()

    VariableNames = {"VariableA", "VariableB", "VariableC", "VariableD"}
    VariableValues = {"1", "Hello", "True", "2.234"}

    For i As Integer = 0 To VariableNames.Length - 1
        SetValue(VariableNames(i), VariableValues(i))
    Next

End Sub

Private Sub SetValue(ByVal Name As String, ByVal value As Object)

    'what do i add here

End Sub


What I have tried:

I've tried a dictionary but it only seems to reference the value not set the variable
Posted
Updated 8-Dec-18 11:42am
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

Yeah, you can't do that.

There is really no such thing as a "global" variable in .NET. The closest you're going to get is a static (Shared in VB.NET) class or Module. I would recommend going the static class route.

The problem with this is that it looks like you're trying to implement a "property bag". That is a collection of key/value pairs where the key is always a string and the value can be any type. Basically, this:
Dim _bag As Dictionary(Of String, Object)

The are a few problem with doing this. One rather nasty one is that you loose type safety. You can set a "variable", really just a key in the dictionary, to any type of value you want. So, if a variable needs to be an integer, but you accidentally write a string to it, there's nothing that will say what you did was wrong until the code reading the "integer" blows up and throws an exception.

Then there's casting values to what's expected, boxing/unboxing, ...

It would be better if you had a fixed set of variables, and if you REALLY needed them to be "global" expose them as Shared properties in a Shared class. You retain type safety, performance, and more easily supported (read: debuggable) code.

But, if you're using "global" variables at all, this is a hint that you probably have to rethink how you're designing your code.
  Permalink  
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 3

I used a reflection

Dim Flags As BindingFlags = BindingFlags.GetField Or BindingFlags.Instance Or BindingFlags.Public
Dim fVar As System.Reflection.FieldInfo = Me.GetType.GetField(ObjectName, Flags)

If TypeOf SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName) Is TextBox Then
    ctrlValue = SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName).Text
ElseIf TypeOf SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName) Is CheckBox Then
    ctrlValue = CType(SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName), CheckBox).Checked
ElseIf TypeOf SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName) Is RadioButton Then
    ctrlValue = CType(SettingsTabControl.TabPages(TabPageIndex).Controls(CtrlName), RadioButton).Checked
End If

fVar.SetValue(Me, ctrlValue)
  Permalink  
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

Thanks Dave. I'll look into the casting method

I thought a simplified example would be more beneficial. here is my exact code.

The section imedialty below are the menu classes. This bit works as expected
Public Class MenuItem

    Public Name As String
    Public Type As TypeEnum

    Enum TypeEnum
        CheckBox
        ComboBox
        TextBox
    End Enum     

    Public Sub New()
    End Sub

End Class

Public Class Menu

    Public MenuItems() As MenuItem
    Public Name As String
    Public LinkedVariable as Object

    Public Sub New()
    End Sub

    Public Sub AddMenuItem(ByVal ItemName As String, _
                           ByVal ItemType As MenuItem.TypeEnum, _
                           ByVal ItemLinkedVariable as Object)   

        If MenuItems Is Nothing Then
            ReDim MenuItems(0)
        Else
            ReDim Preserve MenuItems(MenuItems.Length)
        End If
        MenuItems(MenuItems.Length - 1) = New MenuItem
        MenuItems(MenuItems.Length - 1).Name = ItemName
        MenuItems(MenuItems.Length - 1).Type = ItemType
        MenuItems(MenuItems.Length - 1).LinkedVariable = ItemLinkedVariable 
    End Sub

End Class


Build the menus in the main form class. This bit works as expected

Public Class Form1
    Public Settings As New SettingsForm
    Public Sub CreateMenu()

        Settings.AddMenu("Menu1")

        Settings.Menus(0).AddMenuItem("CheckBoxA", MenuItem.TypeEnum.CheckBox, VariableA)
        Settings.Menus(0).AddMenuItem("TextBoxB", MenuItem.TypeEnum.TextBox, VariableB)
        Settings.Menus(0).AddMenuItem("TextBoxC", MenuItem.TypeEnum.TextBox, VariableC) 

        Settings.AddMenu("Menu2")

        Settings.Menus(1).AddMenuItem("CheckBoxD", MenuItem.TypeEnum.CheckBox, VariableD)
        Settings.Menus(1).AddMenuItem("TextBoxE", MenuItem.TypeEnum.TextBox, VariableE)

        'etc......      

        Settings.Build()

        Settings.Show()

    End Sub
End Class


Public Class SettingsForm
    Public Menus() As Menu

    Public VariableA As Boolean
    Public VariableB As String
    Public VariableC As String
    Public VariableD As Boolean
    Public VariableE As String

    Public Sub New()

        InitializeComponent()

    End Sub

    Public Sub Build()

        SettingsTabControl.TabPages.Clear()

        If Menus IsNot Nothing Then
            For i As Integer = 0 To Menus.Length - 1

                SettingsTabControl.TabPages.Add(Menus(i).Name)
                SettingsTabControl.TabPages(i).Name = Menus(i).Name & "TabPage"
                SettingsTabControl.TabPages(i).Text = Menus(i).Name

                AddSettingsItems(Menus(i), i)

            Next
        End If

    End Sub

    Public Sub AddSettingsItems(ByVal SelectedMenu As Menu, ByVal TabPageIndex As Integer)
        Dim y As Integer = 50
        Dim yinc As Integer = 25

        If SelectedMenu IsNot Nothing Then
            If SelectedMenu.MenuItems IsNot Nothing Then

                For i As Integer = 0 To SelectedMenu.MenuItems.Length - 1

                    Dim formObj As Object

                    'Specific Settings
                    Select Case SelectedMenu.MenuItems(i).Type
                        Case MenuItem.TypeEnum.CheckBox
                            formObj = New CheckBox
                        Case MenuItem.TypeEnum.ComboBox
                            formObj = New ComboBox                            
                        Case MenuItem.TypeEnum.TextBox
                            formObj = New TextBox
                            formObj.TextAlign = HorizontalAlignment.Right
                            formObj.BorderStyle = BorderStyle.FixedSingle
                    End Select

                    formObj.Name = SelectedMenu.MenuItems(i).Name
                    formObj.Location = New Point(25, y)
                    SettingsTabControl.TabPages(TabPageIndex).Controls.Add(formObj)

                    y = y + yinc
                Next
            End If
        End If
    End Sub
End Class


This is the bit i am stuck on i want to be able to set the Variables A,B,C,D,E from the controls that were added to the SettingsTabControl. However i can't work out how to link the Variables to the LinkedVariable objects in each MenuItem. This is what i have but it doesn't work

Private Sub SettingsFromOkButton_Click(sender As Object, e As EventArgs) Handles OkButton.Click

    For m As Integer = 0 To Menus.Length - 1
        For i As Integer = 0 To Menus(m).MenuItems.Length

            Dim currentcontrol As Object = SettingsTabControl.TabPages(m).Controls(Menus(m).MenuItems(i).Name)

            Select Case Menus(m).MenuItems(i).Type
                Case MenuItem.TypeEnum.CheckBox
                    If currentcontrol.CheckedState = True Then
                        Menus(m).MenuItems(i).LinkedVariable = True
                    Else
                        Menus(m).MenuItems(i).LinkedVariable = False
                    End If
                Case MenuItem.TypeEnum.ComboBox


                Case MenuItem.TypeEnum.TextBox
                    Menus(m).MenuItems(i).LinkedVariable = currentcontrol.Text
            End Select

        Next
    Next

    MsgBox(VariableA & vbCrLf _
           VariableB & vbCrLf _
           VariableC & vbCrLf _
           VariableD & vbCrLf _
           VariableE & vbCrLf)

End Sub
  Permalink  

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

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web01 | 2.8.181218.1 | Last Updated 8 Dec 2018
Copyright © CodeProject, 1999-2018
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100