Search code examples
c++-cli

Cannot update User Control Label Text from parent event until the event method reaches return statement


The main form of my application has an event that gets triggered upon completion of a certain task. The event completion launches a background thread and the called method in that thread runs a loop which takes a while to complete. This loop updates (or is supposed to update) the user on what's going on during its run by editing the label->Text property of the UserControl along with a percentage of completion in a different label in the same UserControl. There are some more labels in this UserControl that are updated, but are not of the concern for this question.

Here is how the methods and statements are called.

  1. Event Completed -> Background Thread
  2. Background Thread -> Process()
  3. Process() -> for loop()
  4. for loop() -> UserControl->SetMessage(System::String^ msg) and UserControl->SetPercentage(int Percentage)
  5. (1) UserControl->SetMessage(System::String^ msg) -> stores msg in a private UserControl member and executes this->Invoke->SetMessage_sub()
  6. (2) UserControl->SetPercentage(int prcnt) -> stores prcnt in a private UserControl member and executes this->Invoke->SetPercentage_sub()
  7. (1) SetMessage_sub() -> label1->Text = _msg;
  8. (2) SetPercentage() -> label1->Text = _prcnt;

However, I found that the labels were not getting updated for as long as the loop ran. The labels only updated once the loop finished its run inside Process().

I used the System::Console::WriteLine method to figure out where the problem occurs. I found out that all the methods were being called. But the execution would stop at where the program would reach label->Text property. Please help me out.


Solution

  • I have run into a similar problem recently and found that the GUI update calls must be made from either a thread running in the background or a background worker. Try calling the method that updates your GUI from a background thread or a background worker.

    Edit 1 - it sounds like you've already tried a background thread. Try using a BackgroundWorker object to accomplish the task.

    Edit 2 - upon re-reading your question, it occurred to me that the problem you are facing is the GUI not loading until the event method has returned. I encountered the same problem and asked my question here. To my surprise, all I got was downvotes and no answers. A comment tried to refer me to using BGWorker class to update GUI but none of them read my question carefully. I know background threads and background workers. I have tried both but the GUI does not update until return is called from the event method. In my case, after calling the BackgroundWorker to do the processing, I ran an empty while loop in the event method and called break when the BGWorker finished. But the GUI never updated until break was executed. So, my solution was to create a separate event for the processing and processing completion. The completion of the initial event calls the processing method and then processing method's completion calls the processionf completion event method.