Form.Show()没有显示它的子控件。

3

我有一个表单,名为frmPleaseWait,其中包含一个MarqueeProgressBar和一个Label。在我们的应用程序加载数据时,我想使用它来显示UI。

问题是frmPleaseWait.Show()只显示空白矩形而不显示控件。而frmPleaseWait.ShowDialog()会显示子控件,但不允许UI加载它的数据。

我错了什么?以下是我尝试的代码片段。

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

编辑

:

根据答案和我的尝试进行跟进。

这是我拥有的,但是我会得到一个Cross-Thread ExceptionpleaseWaitInstance.Location = parent.PointToScreen(Point.Empty); 如果我删除那一行,它将运行,但它将在我的屏幕左上角运行,并忽略应用程序的位置。

    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()));
    }
}
2个回答

5

您的表单无法正常工作,原因与shellForm相同。用户界面线程正在加载和绘制控件,它不能同时绘制您的PleaseWait表单。您需要创建一个单独的线程来推动消息循环以保持PW表单的活动状态。您可以按以下方式使其正常工作:

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...
}

使用示例:

        PleaseWait.Create();
        try {
            System.Threading.Thread.Sleep(3000);
        }
        finally {
            PleaseWait.Destroy();
        }

非常棒!运行得很好。跟进问题可能属于它自己的线程,但我该如何让它居中于父窗体或调用表单上?当我调用 PleaseWait.Show(this) 时,显然并没有完全起作用,但现在我看不到明显的方法了...无论如何,感谢您的帮助,我会看看是否可以将最后一个问题解决掉。 - Refracted Paladin
将其传递给Create()方法,设置窗体的位置。 - Hans Passant

1

我遇到了同样的问题,但这个解决方案并没有帮助到我。

我的方法如下: 在 program.cs 中,我实例化了“PleaseWait”窗体,并将其作为参数传递给主窗体:

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

Form1的构造函数就像这样开始:

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

这样做可以轻松更改PleaseWait表单的进度条,而不会遇到线程问题。

敬礼, 沃尔克


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接