Reputation: 3
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
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:
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
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