Form.Show() 不显示其子控件

发布于 2024-08-25 00:10:08 字数 2240 浏览 3 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

凤舞天涯 2024-09-01 00:10:08

您的表单无法工作的原因与 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();
        }

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();
        }
帥小哥 2024-09-01 00:10:08

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

我的方法如下:
在program.cs中,我实例化了“PleaseWait”表单,并将其作为参数提供给主表单:

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

Form1 的构造函数像这样启动:

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

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

问候,
沃尔克

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文