Click here to Skip to main content
15,564,017 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I’ve found I don’t understand the sequence of events when a form loads.
I have a Global variable
public static string LoadingState;
I have a form called LoadProcess which contains one textbox (textBox1000). The code for this form is simply:-
public partial class LoadProcess : Form
 {
     public LoadProcess()
     {
         InitializeComponent();
         textBox1000.Text = Projex.Variables.LoadingState;
     }
     private void LoadProcess_Load(object sender, EventArgs e)
     {
         Refresh();
     }
 }
My main Form1_Load starts with:
Variables.LoadingState = "Identifying user " + "\r \n";
  LoadProcess Loading = new LoadProcess();
  Loading.Visible = true;
Later the code is:-
Variables.LoadingState += "Setting up data adapters " + "\r \n";
Loading.Refresh();
I see the form load but no text appears until a debug break is reached.
Two questions:-
How do I make this form appear and update as the main code executes, and
Is there a better way to keep users appraised about what the code is doing so they don’t think it is hanging?

What I have tried:

Adding Refresh() statements all over the place.
Posted
Updated 16-Oct-21 4:20am

Not sure if I understand the question correctly, but if you want to trigger some action after a form is displayed, you can use Shown event. Have a look at Form.Shown Event (System.Windows.Forms) | Microsoft Docs[^]

So for example, load and show a form, once shown run some logic and update information on the form as the task progresses.
 
Share this answer
 
The problem is that there is but one UI thread, and it is responsible to all Control activities (including Form objects which are derived from Control).
And when you start your app, that is the only running thread - so all code you execute runs on the UI thread. If the thread is executing yoru code, it's not executing "behind the scenes" code which includes display updates. An Event occurring doesn't "interrupt" other code; all code called from an event handler must finish before a second event can be processed.

Paint events - which are what actually updates the display - are low priority, so they don't even get a look in until everything else is dealt with.

And the Load event doesn't cause anything to be displayed at all, it just "prepares" the form for use - the Shown event occurs just after the display itself has been updated to the initial state left over after the Load event and any subsequent code up to the Form.Show or Form.ShowDialog call.

If you want to show progress while a form is loading or doing a long job in the background then you need to move main code into a second thread so that it doesn't block the UI thread and updates can be displayed - which adds it's own problems because only the UI thread can access Controls at all (You will get a cross-threading Exception if you try).
So what I'd recommend is that you look at a BackgroundWorker[^] as it makes thread handling pretty simple, and provides a progress reporting mechanism which allows you to update the UI thread when you have changes to display.
 
Share this answer
 
Comments
BillWoodruff 16-Oct-21 8:54am    
it's a lot simpler than that
note: in this case, it would take me much longer to implement your code and debug it than it would for me to sketch a working solution ... and, i don't have much time right now (health issues). so, i am going to violate my own resolution not to provide complete code solutions.

but, please, study the difference between what you are doing now, and what is shown here: that way, you will learn something, and i will feel less guilt :)

First:

0) assuming the TextBox is in the 'Loading Form, and that the Main Form 'Form1 will update its TextBox:

1) check your TextBox in the 'Loading Form has the 'MultiLine Property set to 'true

2) set a breakpoint just before the call that triggers setting up the data adapters: then single-step (F11) through the code examining the state of variables for anything that is unexpected. this, alone, may indicate what is missing, or, needs to be changed.

Example:
public static class ProJex
{
    public static string LoadingState { set; get; }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    
    LoadProcess Loading = new LoadProcess();
    
    private void Form1_Load(object sender, EventArgs e)
    {
        ProJex.LoadingState = "Identifying user\r\n";
        Loading.SetStateMessage();
        Loading.Owner = this;
        Loading.Show();
    }
    
    // example of setting the status text
    private void button1_Click(object sender, EventArgs e)
    {
        if (Loading == null) return;
        ProJex.LoadingState = "Setting up data adapters\r\n";
        Loading.SetStateMessage();
    }
}


public partial class LoadProcess : Form
{
    public LoadProcess()
    {
        InitializeComponent();
    }
    
    private void LoadProcess_Load(object sender, EventArgs e)
    {
        textBox1000.Text = ProJex.LoadingState;
    }
    
    public void SetStateMessage()
    {
        textBox1000.Text += ProJex.LoadingState;
    }
}
 
Share this answer
 
v3
Comments
ormonds 16-Oct-21 18:15pm    
Thank you, that is very helpful. I've worked through it, but in the LoadProcess class I get for InitialiseComponent "An object reference is required for the non static field...."
Also textBox1000 does not exist in the current context.
BillWoodruff 16-Oct-21 18:26pm    
is textBox1000 sited in the LoadProcess Form ? is your ProJex,Variables class defined as static and LoadingState field defined as static ?

put a breakpoint on the first line of Form1_Load and single-step through the code, examining what's happening. describe the errors in more detail if possible.

cheers, Bill
ormonds 16-Oct-21 21:17pm    
Yes, textBox1000 is in the LoadProcess form.
Projex.Variables class is static
LoadingState string is static
With a breakpoint on line 1 and "Step over Properties and Operators" unselected the line in public void SetStateMessage() "textBox1000.Text += ProJex.LoadingState;" gives the error "The name "textBox1000' does not exist in the current context."

I've tried renaming it to Loading.textBox1000.Text, same thing.
This suggests to me that the SetStateMessage is still in Form1.
I suspect I am missing something obvious, help appreciated.
BillWoodruff 16-Oct-21 22:57pm    
check the LoadProcess form: is the TextBox on the Form named textBox1000 ? does the error occur when you build/compile ?

i tested the code example before posting it; here's the button click handler for a button on Form1 :

private void button1_Click(object sender, EventArgs e)
{
if (Loading == null) return;

ProJex.LoadingState = "Setting up data adapters\r\n";
Loading.SetStateMessage();
}
ormonds 16-Oct-21 23:14pm    
Yes, the TextBox is named textBox1000.
The answer is probably obvious and I've been staring at it too long - tomorrow will do.
Thank you very much for your help.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900