从BackgroundWorker调用Center-parent时不起作用

本文关键字:不起作用 Center-parent 调用 BackgroundWorker | 更新日期: 2023-09-27 17:49:42

在下面的代码中,当UI线程通过buttonBusy_Click调用FormWaitingForm时,formWaitingForm在中心加载和预期的一样是主要形式的。但是,当通过buttonBusyWorkerThread_ClickBackgroundWorker调用时,它将加载到电脑屏幕中央。如何解决这个问题?

public partial class Form1 : Form
{
    WaitingForm formWaitingForm;
    BackgroundWorker bw = new BackgroundWorker(); // Backgroundworker
    public Form1()
    {
        InitializeComponent();
        // Define event handlers
        bw.DoWork += new DoWorkEventHandler(ProcessTick);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
    }
    private void buttonBusy_Click(object sender, EventArgs e)
    {
        // This starts in the center of the parent as expected
        System.Threading.Thread.Sleep(2000);
        formWaitingForm = new WaitingForm();
        formWaitingForm.StartPosition = FormStartPosition.CenterParent;
        formWaitingForm.ShowDialog();
    }
    private void buttonBusyWorkerThread_Click(object sender, EventArgs e)
    {
        // This does not start in the center of the parent
        bw.RunWorkerAsync(); // starts the background worker
    }
    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    { }
    private void ProcessTick(object sender, DoWorkEventArgs e)
    {
        // This does not start in the center of the parent
        System.Threading.Thread.Sleep(2000);
        formWaitingForm = new WaitingForm();
        formWaitingForm.StartPosition = FormStartPosition.CenterParent;
        formWaitingForm.ShowDialog();
    }
}

从BackgroundWorker调用Center-parent时不起作用

FormStartPosition.CenterParent适用于MDI窗体的父窗体,而不适用于所有者窗体。因此,它不会对非mdi表单产生影响。

您可以使用这些扩展方法来打开以其所有者窗体为中心的表单:

public static void ShowCentered(this Form frm, Form owner)
{
    Rectangle ownerRect = GetOwnerRect(frm, owner);
    frm.Location = new Point(ownerRect.Left + (ownerRect.Width - frm.Width) / 2,
                             ownerRect.Top + (ownerRect.Height - frm.Height) / 2);
    frm.Show(owner);
}
public static void ShowDialogCentered(this Form frm, Form owner)
{
    Rectangle ownerRect = GetOwnerRect(frm, owner);
    frm.Location = new Point(ownerRect.Left + (ownerRect.Width - frm.Width) / 2,
                             ownerRect.Top + (ownerRect.Height - frm.Height) / 2);
    frm.ShowDialog(owner);
}
private static Rectangle GetOwnerRect(Form frm, Form owner)
{
    return owner != null ? owner.DesktopBounds : Screen.GetWorkingArea(frm);
}

像这样使用:

formWaitingForm.ShowDialogCentered(owner);

不要在非ui线程中调用它。任何基于windows的UI 101:只有创建线程可以更改对象。

在后台线程中,使用Invoke调用回UI线程