c# - Form.Show() 没有显示它的子控件

标签 c# .net winforms multithreading progress-bar

我有一个表单,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();

编辑

:

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

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

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

最佳答案

您的表单无法正常工作的原因与 shellForm 无法正常工作的原因相同。 UI 线程正忙于加载和绘制控件,它无法同时绘制您的 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();
        }

关于c# - Form.Show() 没有显示它的子控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2428530/

相关文章:

c# - 当 ContractFor 在不同的程序集上时,C# 的代码契约(Contract)不起作用

C++/CLR DataSourceUpdateMode::OnPropertyChanged with TextBox 将光标向左移动

c# - 在 Visual Studio 中使用预览功能和预览语言

c# - Monotouch 全局异常处理

.net - 在 Blazor 和 MVC 中渲染 View

java - 我应该使用什么技术来创建分布式会计软件?

c# - 同步两个 DataGridView 的水平滚动事件

c# - 将附加数据添加到 WinForms ListViewItem

c# - 在 View 中使用 expando 对象?

c# - 使用 DataContractJsonSerializer 反序列化变量类型 JSON 数组