Text Label Won't Update

I have a problem updating the text of a text label.

I’ve tried making it visible and visible again, invalidate, refresh. Nothing works.
If I make it invisible the label disappears but when I make it visible it draws the old text plus the newly set text on top of each other.

I wasted almost two hours trying to figure out why something as simple as updating a label won’t work.

The same code in 2015r3 works just fine. I guess I’m back to 2015r3.

os: Windows 10 64bit

Would you be trying do that in a loop within an invent by any chance ?

Could you post your code ?

Sorry I just pasted chunks of code. I am cramming to meet a deadline and barely had time to even post this.

Here is code to start production: (I posted as a quote so I could bold the lines that change the label)

[quote] 'check to see that we have a valid coil
if PCoilList.ListIndex = -1 or PCoilList.Cell(PCoilList.ListIndex,0) = “” Then
MsgBox “Please select a coil to use for production. You can’t make panels from thin air!”
Return
end if
'check if this is a valid production item
dim t as Integer = Ticks
PWarningUpdate “Starting Production…”
if POrderList.ListIndex > -1 and POrderList.RowTag(POrderList.ListIndex).StringValue <> “” and StartProduction(POrderList.RowTag(POrderList.ListIndex)) Then
dim PID as String = POrderList.RowTag(POrderList.ListIndex)
me.Caption = “Stop Production”

  'findout which export method we are using
  Select Case ExportType
  Case "MRS"
    SendToMachineMRS(PID)
  Case "Beck"
    
    
    
  Case "AMS"
    
  End Select 
  
  
  dim rs as RecordSet = MainDb.SQLSelect("SELECT * FROM Production WHERE ID = '" + PID + "'")
  if rs <> nil and rs.RecordCount > 0 Then
    'reload the order to show changes to the status
    if EditOrderID = rs.Field("OrderID").StringValue Then LoadOrder(rs.Field("OrderID").StringValue,"-1")
    
    'update the status of the order and let everyone know an order has changed
    OrderStatusUpdate rs.Field("OrderID").StringValue
    
    'update the ProductionPriority list
    SendInfoList.Append "Update:Production" +rs.Field("ProductionType").StringValue
    
    'write to log
    SQLps = MainDb.Prepare("INSERT INTO ProductionLog(User,Action,OrderID,ProductionID,LineIDs,TimeStamp) VALUES(?,?,?,?,?,?)")
    SQLps.BindAll 2
    SQLps.BindType(2,SQLitePreparedStatement.SQLITE_INTEGER)
    SQLps.BindType(3,SQLitePreparedStatement.SQLITE_INTEGER)
    SQLps.BindType(4,SQLitePreparedStatement.SQLITE_TEXT)
    SQLps.BindType(5,SQLitePreparedStatement.SQLITE_TEXT)
    dim d as new Date
    SQLps.SQLExecute(system.EnvironmentVariable("COMPUTERNAME"),"StartProduction",rs.Field("OrderID").IntegerValue,PID.CLong,"",d.SQLDateTime)
    MainDb.ErrCheck "PProductionBtn Action 4"
  end if
  #if DebugBuild Then dl.Text = cstr((Ticks-t)/60) + " seconds to start production."
end if
[b]PWarningUpdate[/b][/quote]

Here is code that stops production:

[quote] Dim dialog As New MessageDialog
dialog.Message = “Are you sure you want to cancel this production? This will mark all panels in this order as not produced. If any panels have already been produced they could be produced again.”
dialog.ActionButton.Caption = “Stop Production”
dialog.CancelButton.Visible = True
dialog.CancelButton.Caption = “Cancel”
dialog.CancelButton.Default = true
Dim dialogButton As MessageDialogButton
dialogButton = dialog.ShowModalWithin(Self)
dim t as Integer = Ticks
PWarningUpdate “Stopping Production…”

if dialogButton =  dialog.ActionButton and POrderList.ListIndex > -1 and POrderList.RowTag(POrderList.ListIndex).StringValue <> "" Then
  dim PID as String = POrderList.RowTag(POrderList.ListIndex)
  if CheckProduction.Ubound > -1 Then CheckProduction.Remove(0)
  MainDb.SQLExecute("UPDATE Production SET Status = '1' WHERE ID = '" + PID + "'")
  MainDb.ErrCheck "PProductionBtn Action 1"
  MainDb.SQLExecute("DELETE FROM ProductionProgress WHERE ProductionID = '" + PID + "'")
  MainDb.ErrCheck "PProductionBtn Action 2"
  MainDb.SQLExecute("UPDATE OrderLines SET Status = '1' WHERE ProductionID = '" + PID + "'")
  MainDb.ErrCheck "PProductionBtn Action 3"
  
  dim rs as RecordSet = MainDb.SQLSelect("SELECT * FROM Production WHERE ID = '" + PID + "'")
  if rs <> nil and rs.RecordCount > 0 Then
    'reload the order to show changes to the status
    if EditOrderID = rs.Field("OrderID").StringValue Then LoadOrder(rs.Field("OrderID").StringValue,"-1")
    
    'update the status of the order and let everyone know an order has changed
    OrderStatusUpdate rs.Field("OrderID").StringValue
    
    'update the ProductionPriority list
    SendInfoList.Append "Update:Production" +rs.Field("ProductionType").StringValue
    
    'write to log
    SQLps = MainDb.Prepare("INSERT INTO ProductionLog(User,Action,OrderID,ProductionID,LineIDs,TimeStamp) VALUES(?,?,?,?,?,?)")
    SQLps.BindAll 2
    SQLps.BindType(2,SQLitePreparedStatement.SQLITE_INTEGER)
    SQLps.BindType(3,SQLitePreparedStatement.SQLITE_INTEGER)
    SQLps.BindType(4,SQLitePreparedStatement.SQLITE_TEXT)
    SQLps.BindType(5,SQLitePreparedStatement.SQLITE_TEXT)
    dim d as new Date
    SQLps.SQLExecute(system.EnvironmentVariable("COMPUTERNAME"),"StopProduction",rs.Field("OrderID").IntegerValue,PID.CLong,"",d.SQLDateTime)
    MainDb.ErrCheck "PProductionBtn Action 4"
  end if
  me.Caption = "Start Production"
  #if DebugBuild Then dl.Text = cstr((Ticks-t)/60) + " seconds to stop production."
end if
[b]PWarningUpdate[/b][/quote]

Here is a the label update model I added to try to better trace what all was changing the label: (I tried about everything in the way of refreshing)

PWarningUpdate(T as String = "")
if t = "" Then
    PWarning.Text = ""
    PWarning.Visible = False
    PWarning.Refresh
  else
    PWarning.text = t
    PWarning.Visible = True
    PRect.Invalidate
    PWarning.Refresh
  end if
End Sub

Neil, maybe you want to come back to this when your project is complete.

So, basically in 2016R3 (I guess) under Win 10 Pro 64 bit if I remember right another thread, you are no longer able to update labels.

I tried to find a way to obtain what you describe to no avail. I asked you if the code was in a loop because, labels no longer update under Windows while in an event, only at the end.

Correct

Sad :frowning:

Yes it’s a button action event. I did a sample program where a textbox.textchanged event changed a label, and it updated just fine.

I’ll summarize:

Press button a once:
label changed to “Starting Production…” (at beginning of event) refresh make this change display immediately
label changed to “” (at end of event) this change does not display.

Timers and other methods with db actions executing here.

Press button a 2nd time:
label changed to “Stopping Production…” (at beginning of event) refresh make this change display to “Starting Production…” and “Stopping Production…” overtop of each other.

label changed to “” (at end of event) this change does not display.

a band-aid would be create TWO labels… one that says “Start” one that says “Stopping”
and flip the VISIBLE attribute, this should happen immediately regardless of OS

its crude, but effective

OK. That is what I supposed.

Note that the fact that the uI no longer updates while an event is not over will be generalized for all systems, and is the same for Mac, Windows and Linux. It is the way modern programming goes.

The solution is to move your long process to the Run event of a thread, and to effect the changes in label display in a timer you trigger from the thread (one cannot manipulate the UI from the run event of a thread).

For that, the new framework Xojo.Core.Timer callLater is very convenient : http://developer.xojo.com/xojo-core-timer$CallLater

Ok Thanks. I guess my (incorrect) assumption was that it would either not update at all or update correctly.

Quick & simple this works on Windows 10 32 bit

Start a new desktop project
Put a label on a the default window
Put a button
in the buttons action event put

  label1.text = "starting"
  label1.Refresh
  
  dim tNow as Double = Microseconds
  
  while Microseconds < tNow + 1000000
  wend
  
  label1.text = "ending"
  label1.Refresh

Run & press the button
You should see it change to “starting” then a little but later “ending”

Norman,

That works on my 64 bit system as well even using Xojo 2016r3.

The problem that I’ve reported is obviously (to me) a bug, but It’s in a project with about 12k lines of code. I don’t have the time to isolate the problem so I’m back to 2015r1 to cram this project to the finish line.

@Michel Bujardet I looks more like a problem with old and new text value being draw on top of each other rather than a refresh issue.

Thanks to everyone for their help.

I have been using 2015R4.1 to build the apps I placed in the Windows Store, because of some issues with the converter and 2016R3 since resolved.

It is alright to go back a bit while you have not resolved some problems. Basically, if you do not need HiDPI, 2015R4.1 is very nice.

OK how to reproduce it in a smaller project I don’t know. Here you can see it in gory detail. This is the code in the textbox.textchange event:

PWarning.text = me.text

OK I’ve pinpointed the bug. It only happens when a label is in a pagepanel inside a tab panel with transparency off.

Project File

Bug Case [45856]

Can’t see the screenshot because OneDrive…
I’m not seeing any issues here on Mac, so it might be a Windows only issue (those are always fun.)

While it doesn’t answer your problem, I think this is a gateway to talk about moving intensive processing to a thread. Your UI would be able to update itself, and would no longer behave as it’s not responding.

As shown in the attached project file the bug has nothing to do with processing or refreshing. It has to do with a label not clearing old text before drawing new text value.

Just tested on Mac. Problem is Windows only.

Well since you can reproduce it, and we’ve narrowed it down to Windows only, and you have a sample project, you should file a bug report so it can get looked at and fixed.

Yeah, I did that when I opened this thread. I posted the bug case here as soon as I pinpointed the problem.

You can replace a transparent label by a Canvas.

A little overkill for what I’m doing. Considering the fact that setting the label to transparent takes care of the problem.