Form.Show() is not showing it's child controls

2019-03-01 03:23发布

问题:

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()));
    }
}

回答1:

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();
        }


回答2:

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