3

I am making a form that has groups of controls that I want to visibly enable/disable with a related toggle button (let's call them Group Toggles). Each group has a different variety of control types, so I made a common procedure to handle the toggling:

'constants for control ForeColors
Public Enum LabelForeColor
    Default = 8355711
    Off = 14277081
End Enum

Public Enum ListForeColor
    Default = 4210752
    Off = 12566463
End Enum

Public Sub EnableControl(Ctrl As Control, Enabled As Boolean)
    With Ctrl
        Select Case Ctrl.ControlType
            Case acLabel
                If Enabled Then .ForeColor = LabelForeColor.Default Else .ForeColor = LabelForeColor.Off
                Debug.Print "LABEL", .ForeColor

            Case acListBox
                If Enabled Then .ForeColor = ListForeColor.Default Else .ForeColor = ListForeColor.Off
                .Enabled = Enabled
                Debug.Print "LIST", .ForeColor

            Case acCommandButton
                .Enabled = Enabled
                Debug.Print "BUTTON", "NA"

            Case acCheckBox
                .Enabled = Enabled
                Debug.Print "CHECK", "NA"

            Case Else
                Debug.Print "Control [" & .Name & "] is not of a type that EnableControl can handle."

        End Select
    End With
End Sub

Each group of controls is represented by a collection. When the form is loaded, every control with a particular tag property is added to the corresponding collection. The Group Toggles are not added to any collection and instead have event procedures that look like this:

Private Sub ToggleGroup1_AfterUpdate()
    Dim State As Boolean
    'a public function that converts the toggle button's value to a boolean
    State = FormCommon.ToggleButtonState(ToggleGroup1.Value)

    Dim iCtrl As Control
    For Each iCtrl In Controls_ByPlant
        FormCommon.EnableControl iCtrl, State
    Next iCtrl
End Sub

When I click on a GroupToggle, all of the controls in the corresponding group visibly change appropriately, except for the labels. After an hour of troubleshooting, here's what I know:

  • The ForeColor property of the label does change, but not visibly.
  • When I call EnableControl on a label outside of a loop, the label visibly changes.
    • It doesn't matter if I pass the label object specifically to the subroutine or if I pass it from its group collection; the change is visible in both cases
  • If I toggle-disabled a label as part of the Group Toggle event and then call EnableControl specifically on that label to try to disable it again, there is no visible change (probably because the ForeColor property is already set to the "off" color)
  • Turning screen updating off with Application.Echo while the Group Toggle event runs and then turning it back on at the end of the event does not make a difference.
  • Making the Group Toggle event run with a For i = 1 to .Count instead of a For Each does not make a difference.
  • This problem also occurs when changing a different visual property instead, such as ForeTint.
  • (Per comments) Repaint does not make a difference
  • (Per comments) DoEvents does not make a difference

Why is this happening?

(First ever question, so apologies if I messed something up in the post)

Ryan W.
  • 33
  • 6
  • Use Conditional Formatting, not VBA. – June7 Oct 03 '17 at 21:00
  • @June7 I'm not sure I know what you're talking about. – Ryan W. Oct 03 '17 at 21:04
  • Bing: Access Conditional Formatting. https://support.office.com/en-us/article/Change-the-appearance-of-a-control-by-using-conditional-formatting-6BA9E9FA-4347-4183-B335-44E43B05E22F – June7 Oct 03 '17 at 21:06
  • However, available only for textbox and combobox. If form is in Continuous or Datasheet view, VBA won't work because all instances of a control are affected. I have used VBA to modify properties of controls on Single view form. I will have to look at your code some more later. – June7 Oct 03 '17 at 21:14
  • @June7: I'm pretty sure this is about a single form. – Andre Oct 03 '17 at 22:46
  • 2
    I ran your code on a `For Each iCtrl In Me.Controls` loop, and it worked for all specified controls, including labels. Access 2010 here. You might try a `myForm.Repaint` after the loop. Can you post a screenshot of your form? – Andre Oct 03 '17 at 22:49
  • did adding "DoEvents" within your loop help at all? – Krish Oct 04 '17 at 10:20
  • @Andre At your suggestion, I tried both `Me.Repaint` in the event procedure and `Ctrl.Parent.Repaint` in the common procedure (`Ctrl.Parent.Parent.Repaint` for labels, which are bound to other controls). Neither worked. I will try to get you a screenshot of my form. – Ryan W. Oct 04 '17 at 14:35
  • @krishKM At your suggestion, I put `DoEvents` in the event procedure. It did not change anything. – Ryan W. Oct 04 '17 at 14:36
  • TBH, I didn't really expect it to do anything. :( If the problem irks you enough, and you can create a sample database with the form, the necessary code and some sample data (if needed), I'd have a look at it. – Andre Oct 04 '17 at 14:38
  • add doevents after changing .forecolor value and tell me if that worked? – Krish Oct 04 '17 at 14:48
  • @krishKM I did as you suggested. Nothing changed... – Ryan W. Oct 04 '17 at 15:24
  • 1
    @Andre [Dropbox link](https://www.dropbox.com/s/en81duie7te560y/ToggleGroupSample.accdb?dl=0) – Ryan W. Oct 04 '17 at 15:33

1 Answers1

2

This was interesting, but somewhat anticlimactic.

Your code does work for the labels, but what happens is this:

  • All labels are associated with input controls (as it is usual)
  • When you deactivate a group, you disable the input controls (.Enabled = Enabled)
  • This automatically sets the associated labels to a (system defined) light gray text color which cannot be changed.
  • This "disabled label" color is very similar to your LabelForeColor.Default color, so it is hard to see the change when toggling. But it does change.

Change your color constants to make the effect more visible:

Public Enum LabelForeColor
    Default = vbRed ' 8355711
    ' the "Off" color is never visible, unless you add an un-associated label to a group
    Off = vbBlue ' 14277081
End Enum

enter image description here

Edit: your test code FormCommon.EnableControl iCtrl, False works, because it only affects the label, but doesn't disable its associated list box.

Andre
  • 26,751
  • 7
  • 36
  • 80