Bug? Standard ListView Requires sleep for Color Change (B4A-8.50)

Discussion in 'Bugs & wishlist' started by MrKim, Nov 7, 2018.

  1. MrKim

    MrKim Active Member Licensed User

    I added the code to change colors (If O.OSStatus = "C" Then...) but it had no effect until I added the
    Sleep(0).
    All lines remained the default - white.
    Not a big deal but it took awhile to figure out what was going on.
    Code:
    Sub Globals
      
    Dim List1 As ListView
    .
    .
    .
            
    Do While Crsr.NextRow
                O.OSID = Crsr.GetLong(
    "Os_ID")
                O.JobNum = Crsr.GetString(
    "Os_JobNum")
                O.Rel = Crsr.GetString(
    "Os_ReleaseNum")
                O.Os_SeqNum = Crsr.GetString(
    "Os_SeqNum")
                O.Tk_WCName = Crsr.GetString(
    "Os_WCCode")
                O.OSStatus = Crsr.GetString(
    "Os_Status")
                
    If O.OSStatus = "C" Then
                    List1.TwoLinesLayout.Label.TextColor = 
    Colors.Red
                
    Else
                    List1.TwoLinesLayout.Label.TextColor = 
    Colors.White
                
    End If
                Sleep(
    0)
                
    If Crsr.GetInt("Os_SubContract") = 0 Then
                    List1.AddTwoLines2(
    NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null"""-Status: " & O.OSStatus), "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 02) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 02), O)
                
    End If
    .
    .
    .
    More was revealed. See next post.
     
    Last edited: Nov 8, 2018 at 12:11 AM
  2. MrKim

    MrKim Active Member Licensed User

    Well, the problem turned out to be more difficult to solve than I thought.
    Turns out the code above was turning the List Item red BEFORE the one that was supposed to be Red.
    So I tried this:
    Code:
    Do While Crsr.NextRow
                O.OSID = Crsr.GetLong(
    "Os_ID")
                O.JobNum = Crsr.GetString(
    "Os_JobNum")
                O.Rel = Crsr.GetString(
    "Os_ReleaseNum")
                O.Os_SeqNum = Crsr.GetString(
    "Os_SeqNum")
                O.Tk_WCName = Crsr.GetString(
    "Os_WCCode")
                O.OSStatus = Crsr.GetString(
    "Os_Status")
                
    If Crsr.GetInt("Os_SubContract") = 0 Then
                    List1.AddTwoLines2(
    NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null"""-Status: " & O.OSStatus), "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 02) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 02), O)
                
    End If
                Sleep(
    0)
                
    If O.OSStatus = "C" Then
                    List1.TwoLinesLayout.Label.TextColor = 
    Colors.Red
                
    Else
                    List1.TwoLinesLayout.Label.TextColor = 
    Colors.White
                
    End If
    And it turned the Item AFTER the one that was supposed to be red red.
    THIS works:
    Code:
    Do While Crsr.NextRow
                O.OSID = Crsr.GetLong(
    "Os_ID")
                O.JobNum = Crsr.GetString(
    "Os_JobNum")
                O.Rel = Crsr.GetString(
    "Os_ReleaseNum")
                O.Os_SeqNum = Crsr.GetString(
    "Os_SeqNum")
                O.Tk_WCName = Crsr.GetString(
    "Os_WCCode")
                O.OSStatus = Crsr.GetString(
    "Os_Status")
                
    If Crsr.GetInt("Os_SubContract") = 0 Then
                    List1.AddTwoLines2(
    NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null"""-Status: " & O.OSStatus), "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 02) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 02), O)
                
    End If
                
    If O.OSStatus = "C" Then
                    List1.TwoLinesLayout.Label.TextColor = 
    Colors.Red
                
    Else
                    List1.TwoLinesLayout.Label.TextColor = 
    Colors.White
                
    End If
                Sleep(
    0)
     
  3. OliverA

    OliverA Well-Known Member Licensed User

    I don't think it is a bug. This has to do with events and how the usage or not usage of SLEEP impacts event processing. Setting the text color is an event (a guess here, due to what you are experiencing). If you do not use sleep and process your Do While loop, events are generated, but not executed until the Do While finishes processing and your code finishes and returns in such a way that event processing happens (by waiting for the next event) and then all the events are processed at once. Using SLEEP, you can "force" events to be processed. In your first listing (post #1) you create a "TextColor" event, use SLEEP to have it processed and then set your text. As you can see, the two items are out of sync. In your second example, you add text, use SLEEP to let the system process events and then create a "TextColor" event. Once more, creating the text and setting the color are out of sync. Finally, you create the text, then change the color and then use SLEEP to process the events in the correct order.
     
    MrKim likes this.
  4. DonManfred

    DonManfred Expert Licensed User

    Not a bug. You can NOT define different colors for the same type of items in a Listview. ALL Items of the same type share the same color.

    OneLine, twolines, twolineandbitmap.

    Use xCustomListview and you have much more control. You even can use a different color on each item

    Alternative: You can use CharsequenceBuilder to set the Text with different Colors.
    Code:
    For i = 1 To 100
       ListView1.AddSingleLine(cs.Initialize.Color(
    Rnd(0xFF000000, -1)).Alignment("ALIGN_CENTER").Append($"Item #${i}"$).PopAll)
    Next
     
    Last edited: Nov 8, 2018 at 5:07 AM
    mangojack, MrKim and Erel like this.
  5. Erel

    Erel Administrator Staff Member Licensed User

    @DonManfred answer is 100% correct. Please start a new thread in the questions forum for further discussion.
     
    MrKim likes this.
  6. MrKim

    MrKim Active Member Licensed User

    Thank you!
    This works like a charm:
    Code:
    If Crsr.GetInt("Os_SubContract") = 0 Then
       
    If O.OSStatus = "C" Then Clr = Colors.Red Else Clr = Colors.White
       cs.Initialize.Color(Clr).Append(
    NumberFormat(Crsr.GetString("Os_SeqNum"),0 ,0 ) & " Op: " & Crsr.GetString("Os_WCCode") & IIF(O.OSStatus = Null"""-Status: " & O.OSStatus)).PopAll
       List1.AddTwoLines2(cs, 
    "Start By: " & Crsr.GetString("Os_StartbyDate") & " Setup: " & NumberFormat(Crsr.GetString("Os_SetupTime"), 02) & " Run: " & NumberFormat(Crsr.GetString("Os_RunTime"), 02), O)
    End If
    I just wish I understood why:p
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice