2

I have a form, frmPleaseWait, that has a MarqueeProgressBar and a Label that I want to use when the UI is loading the data in a poorly structured app we have.

The problem is that frmPleaseWait.Show() shows the form but not the controls in it. It is just a white rectangle. Now frmPleaseWait.ShowDialog() shows the child controls but doesn't let the UI load it's data.

What am I missing? Below is a code snippet from where I am trying this.

        PleaseWait = new frmPleaseWait();
        PleaseWait.Show(this);

        // Set all available HUD values in HUD Object
        HUD.LastName = GetCurrentRowVal("LastName").Trim();
        HUD.FirstName = GetCurrentRowVal("FirstName").Trim();
        HUD.PersonId = Convert.ToInt32(GetCurrentRowVal("PersonID").Trim());
        HUD.SSn = GetCurrentRowVal("SSN").Trim();
        HUD.MiddleName = GetCurrentRowVal("MiddleName").Trim();
        HUD.MasterID = ConnectBLL.BLL.DriInterface.CheckForDriId(HUD.PersonId).ToString();

        // This loads numerous UserControls with data
        shellForm.FormPaint(HUD.PersonId);

        PleaseWait.Close();

Edit

:

Follow up based on answers and my attempt.

This is what I have but I get a Cross-Thread Exception on pleaseWaitInstance.Location = parent.PointToScreen(Point.Empty); If I remove that line it will run but it runs in the top left corner of MY screen and ignores the position of the app.

    public partial class frmPleaseWait : XtraForm
{
    public frmPleaseWait()
    {
        InitializeComponent();
    }

    private static frmPleaseWait pleaseWaitInstance;

    public static void Create(XtraForm parent)
    {
        var t = new System.Threading.Thread(
            () =>
                {
                    pleaseWaitInstance = new frmPleaseWait();
                    pleaseWaitInstance.FormClosed += (s, e) => pleaseWaitInstance = null;
                    pleaseWaitInstance.StartPosition = FormStartPosition.Manual;
                    pleaseWaitInstance.Location = parent.PointToScreen(Point.Empty);
                    Application.Run(pleaseWaitInstance);
                });
        t.SetApartmentState(System.Threading.ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
    }

    public static void Destroy()
    {
        if (pleaseWaitInstance != null) pleaseWaitInstance.Invoke(new Action(() => pleaseWaitInstance.Close()));
    }
}
Refracted Paladin
  • 11,636
  • 32
  • 115
  • 224

2 Answers2

4

Your form doesn't work for the same reason shellForm doesn't work. The UI thread is busy loading and painting the controls, it can't paint your PleaseWait form at the same time. You'll need to create a separate thread that pumps a message loop to keep your PW form alive. You could make it work like this:

public partial class PleaseWait : Form {
    private static PleaseWait mInstance;
    public static void Create() {
        var t = new System.Threading.Thread(() => {
            mInstance = new PleaseWait();
            mInstance.FormClosed += (s, e) => mInstance = null;
            Application.Run(mInstance);
        });
        t.SetApartmentState(System.Threading.ApartmentState.STA);
        t.IsBackground = true;
        t.Start();
    }
    public static void Destroy() {
        if (mInstance != null) mInstance.Invoke(new Action(() => mInstance.Close()));
    }

    private PleaseWait() {
        InitializeComponent();
    }
    //etc...
}

Sample usage:

        PleaseWait.Create();
        try {
            System.Threading.Thread.Sleep(3000);
        }
        finally {
            PleaseWait.Destroy();
        }
Hans Passant
  • 873,011
  • 131
  • 1,552
  • 2,371
  • absolutely awsome! works pretty well. Follow up question that may belong in it's own thread but how would I get this to center on the Parent, or calling form? I had been using `PleaseWait.Show(this)` when I called which, obviously, wasn't fully working but now I don't see an obvious way....anyway, thanks for the help and I'll see if I can piece that last one in there. – Refracted Paladin Mar 12 '10 at 05:17
  • Pass it to the Create() method, set the form's Location. – Hans Passant Mar 12 '10 at 05:59
1

I encountered the same problem, and this solution did not help me, though.

My way was the following: In program.cs I instanced the 'PleaseWait'-Form and gave this as a parameter to the main Form:

    pleaseWaitForm pleaseWait = new pleaseWaitForm();
    Application.Run(new Form1(pleaseWait));

The Form1's constructor starts then like this:

    public Form1(pleaseWaitForm pleaseWait)
    {
        InitializeComponent();
        pleaseWait.Show();
    }

This way it was easy to change i.e. a progressbar of the PleaseWait Form without getting troubles with the thread.

Regards, Volker

Volker
  • 11
  • 1