derickO
derickO

Reputation: 3

How change 90 button colors from another form(one at a time) using combobox.

I'm developing a system called Production Monitoring System. I have a Combobox1 that loads the 90 button names from another form, then I also have Combobox2, om my combobox2, it have have values(MASS PRO, NEW TRIAL, MACHINE ERROR, ETC...). If the user chooses MASS PRO then the button that is selected from the Combobox1 will turn it's back color to GREEN. here is my sample Code. I tried it but nothing happens. My problem is how to change my buttons background color based on the state that i selected from CB2.

 If ComboBox2.SelectedItem = "MASS PRO" Then
        ComboBox1.SelectedItem.ForeColor = (Color.Green)
    ElseIf ComboBox2.Text = "NEW TRIAL" Then
         ComboBox1.SelectedItem.ForeColor = Color.Blue
    ElseIf ComboBox2.Text = "FIRST MOULDING" Then
         ComboBox1.SelectedItem.ForeColor = Color.Orange
    ElseIf ComboBox2.Text = "STOP PRODUCTION" Then
        ComboBox1.SelectedItem.ForeColor = Color.Red
    ElseIf ComboBox2.Text = "MASS PRO w/ QN" Then
        ComboBox1.SelectedItem.ForeColor= Color.Yellow
    ElseIf ComboBox2.Text = "MACHINE ERROR" Then
        ComboBox1.SelectedItem.ForeColor= Color.DarkRed
    End If

Upvotes: 0

Views: 53

Answers (2)

aybe
aybe

Reputation: 16662

To change the background color of some controls according a state, you could implement different states that your UI would follow:

Here's a simple example with only 1 color, you will want to extend it:

Public MustInherit Class State

    MustOverride ReadOnly Property Color As Color
    MustOverride ReadOnly Property Description As String

End Class

Public NotInheritable Class ErrorState
    Inherits State

    Public Overrides ReadOnly Property Color As Color
        Get
            Return Color.Red
        End Get
    End Property

    Public Overrides ReadOnly Property Description As String
        Get
            Return "Error"
        End Get
    End Property
End Class

Public NotInheritable Class NormalState
    Inherits State

    Public Overrides ReadOnly Property Color As Color
        Get
            Return Color.Green
        End Get
    End Property

    Public Overrides ReadOnly Property Description As String
        Get
            Return "Normal"
        End Get
    End Property
End Class

Usage example:

Public Class Form1
    Private _myControls As List(Of Control)

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        ' populate available states
        Dim list = New List(Of State)()
        list.Add(New NormalState)
        list.Add(New ErrorState)
        ComboBox1.DisplayMember = "Description"
        ComboBox1.DataSource = list

        ' populate controls affected by current state
        _myControls = New List(Of Control)
        _myControls.Add(Button1)
        _myControls.Add(Button2)


    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged

        ' guard
        If _myControls Is Nothing
            Return
        End If

        ' update controls back color according selected state
        Dim comboBox = CType(sender, ComboBox)
        Dim state = CType(comboBox.SelectedItem, State)

        For Each control As Control In _myControls
            control.BackColor = state.Color
        Next

        ' etc ...

    End Sub
End Class

I kept things simple by populating a single category of controls that would be affected.


Alternatively you can use an enum to group related controls and color them, using Control.Tag property:

enter image description here

enter image description here

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        ' populate available states
        Dim list = New List(Of State)()
        list.Add(New NormalState)
        list.Add(New ErrorState)
        ComboBox1.DisplayMember = "Description"
        ComboBox1.DataSource = list

        ' tag controls
        Button1.Tag = StateTag.Important
        Button2.Tag = StateTag.Useless


        ComboBox1.SelectedIndex = -1

    End Sub

    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged

        ' update controls back color according selected state and their tag
        Dim comboBox = CType(sender, ComboBox)

        If comboBox.SelectedIndex = -1 Then
            Return
        End If

        Dim state = CType(comboBox.SelectedItem, State)

        For Each control As Control In Controls

            Dim o = control.Tag
            If o Is Nothing Then Continue For

            Dim defined = [Enum].IsDefined(GetType(StateTag), o)
            If Not defined Then Continue For

            Dim stateTag = [Enum].Parse(GetType(StateTag), o)
            Dim color = state.GetStateTagColor(stateTag)
            control.BackColor = color
        Next

    End Sub
End Class

Public Enum StateTag
    Important
    Useless
End Enum

Public MustInherit Class State
    MustOverride ReadOnly Property Description As String


    Public MustOverride Function GetStateTagColor(ByVal tag As StateTag) As Color
End Class

Public NotInheritable Class ErrorState
    Inherits State

    Protected ReadOnly _dictionary As Dictionary(Of StateTag, Color)

    Sub New()
        _dictionary = New Dictionary(Of StateTag, Color)()
        _dictionary.Add(StateTag.Important, Color.Red)
        _dictionary.Add(StateTag.Useless, Color.Green)
    End Sub

    Public Overrides ReadOnly Property Description As String
        Get
            Return "Error"
        End Get
    End Property

    Public Overrides Function GetStateTagColor(ByVal tag As StateTag) As Color
        Return _dictionary.Item(tag)
    End Function
End Class

Public NotInheritable Class NormalState
    Inherits State
    Protected ReadOnly _dictionary As Dictionary(Of StateTag, Color)

    Sub New()
        _dictionary = New Dictionary(Of StateTag, Color)()
        _dictionary.Add(StateTag.Important, Color.Cyan)
        _dictionary.Add(StateTag.Useless, Color.Magenta)
    End Sub

    Public Overrides ReadOnly Property Description As String
        Get
            Return "Normal"
        End Get
    End Property

    Public Overrides Function GetStateTagColor(ByVal tag As StateTag) As Color
        Return _dictionary.Item(tag)
    End Function
End Class

The good thing is that you won't have to use error-prone string anymore by using a bit of OOP (your code becomes clearer/simpler at the same time).

Upvotes: 0

jmcilhinney
jmcilhinney

Reputation: 54457

Think about it. You said yourself that you load the Button NAMES into ComboBox1. What would be the use in changing the ForeColor of the NAME of a Button? The name is not the Button. You have to get the actual Button.

You have a number of choices but one of them would be to add all the Buttons themselves to a list and bind that to the ComboBox, setting the DisplayMember to "Name". That way, the items actually are the Buttons themselves while just the Name values will be displayed.

Another option would be to use the name from the ComboBox to get the Button from the form's Controls collection, e.g.

Me.Controls(buttonName).ForeColor = myColor

Another option would be to put the Buttons into an array and then use the SelectedIndex of the ComboBox to get the right one by index.

Upvotes: 1

Related Questions