Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Button.Visible = true; fails to set the button to visible when activated within a function

Tags:

c#

winforms

I haven't been able to find anyone else having this same problem, so hopefully someone might have some ideas or be able to point me to another answer.

When a function is run by pressing a button on the form, another button should become visible. However, the button never shows up even though it is the first thing in the function. All of the other code in the function works perfectly.

Here is the code:

private void trackbar_Change(object sender, EventArgs e)
{
    button.Visible = true;
    progressbar.Visible = true;

    ...

    progressbar.Visible = false;
    button.Visible = false;
}

The progress bar shows up and works fine, and all other code in the function works fine as well, but the button never shows up at all.

If I remove button.Visible = false; from the end of the function, then the button DOES show up, but only after all other code has executed. Like this:

private void trackbar_Change(object sender, EventArgs e)
{
    button.Visible = true;
    progressbar.Visible = true;

    ...

    progressbar.Visible = false;
    //button.Visible = false;
}

Commenting out that line causes the button to show up. Now if I add a message box after the button line, then it also works.

private void trackbar_Change(object sender, EventArgs e)
{
    button.Visible = true;
    MessageBox.Show("Button should be visible now");
    progressbar.Visible = true;

    ...

    progressbar.Visible = false;
    button.Visible = false;
}

Adding the message box after the button line caused the button to show up at the right time.

Does anyone have any ideas why this button is behaving this way?

like image 272
blue Avatar asked Dec 21 '22 01:12

blue


2 Answers

It sounds like the GUI thread is busy. Try forcing the screen update by calling Application.DoEvents(), for example:

button.Visible = true;
progressbar.Visible = true;
Application.DoEvents();

DoEvents() will force all the message in the message queue to be processed.

A better solution would be to move the long running thread of main UI thread. Use a BackgroundWorker for the task.

It will make the form more responsive overall. For example you would be able to interact with the form and it won't turn 'white'. Implementing the BackgroundWorker is simple and a must for long running processes on the main UI thread,

like image 146
Philip Fourie Avatar answered Dec 23 '22 16:12

Philip Fourie


The issue is that you're executing a long running process on the UI thread and so setting the button to visible won't happen until the thread is free. However, by the time the thread is free you have set visible to false.

The best way to do this is to execute the long running process on a background worker so that the UI thread isn't blocked. And the reason the progress bar works is because it runs on a different thread.

There is one other way -- but probably less correct -- and that's to issue a Refresh on the form after setting visible to true.

Let me know if you need help with the BackgroundWorker but it's pretty straight forward.

like image 30
Mike Perrenoud Avatar answered Dec 23 '22 16:12

Mike Perrenoud