简体   繁体   中英

Managing the dialog form in C#

On click of a button I have this code with is should show a dialog on top of the current form and display text, wait for one second, change the text and then finally close it:

Form p = new Form();
p.ShowDialog();

p.Text = "Start.";
Thread.Sleep(1000);

p.Text = "Counting.";
Thread.Sleep(1000);

p.Text = "End.";
Thread.Sleep(1000);

p.Close();

However once it executes p.ShowDialog(); it stops the code until the form p is closed and it doesn't work as I intended it to. Can I get some guidance on this? Not necessarily the solution, but at least maybe some keywords I could google on?

UPDATE: due to the difficulties I am facing trying to access business logic, which is irrelevant to the problem, I am delaying providing the working example. Stay tuned and sorry :)

SOLUTION: what I did is in fact used Show() instead of ShowDialog() . Since i was impossible to access form from business logic, BackgroundWorker came in handy and was being used between them. I cannot share any code or the layout of the project structure, but in conclusion, the accepted answer's main statement was the key to the solution :)

That is the point of ShowDialog(). It creates a modal form and does not return control to the calling function until you are done. If it doesn't need to be modal, then use .Show(). If it does need to be modal, then put code in the Form Load method to update the text as needed.

http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx

taken from the link above:

When this method is called, the code following it is not executed until after the dialog box is closed.

if you want to form to display whatever it is you want to display you should write the code inside the the form itself, do that in an eventhandler of the form show event.

As you have found, ShowDialog is a blocking method that does not return until the dialog is closed. Your code to change the text and handle the delay needs to be within the dialogue itself.

However, it's worth noting the next problem that you'll find: if you call Thread.Sleep(1000) from the UI thread, your application will become unresponsive for 1 second at a time. This is probably not what you're aiming for! I'd suggest you look into the Timer or BackgroundWorker classes to handle this more smoothly.

Check this out:

public partial class Form2 : Form
{
    delegate void SetTextCallback(string text);
    delegate void CloseFormCallback();

    public Form2()
    {
        InitializeComponent();

        new Thread(DoMagic).Start();
    }

    public void DoMagic()
    {
        this.SetText("Start.");

        Thread.Sleep(1000);

        this.SetText("Counting.");
        Thread.Sleep(1000);

        this.SetText("End");

        Thread.Sleep(1000);

        this.CloseForm();
    }

    private void CloseForm()
    {
        if (this.InvokeRequired)
        {
            CloseFormCallback c = new CloseFormCallback(CloseForm);
            this.Invoke(c);
        }
        else
        {
            this.Close();
        }
    }

    private void SetText(string text)
    {
        if (this.label1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.label1.Text = text;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM