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

时间:2014-03-12 19:59:47

标签: c# multithreading winforms backgroundworker

在下面的代码中,当从UI线程通过buttonBusy_Click调用FormWaitingForm时,formWaitingForm加载到中心  主要形式如预期。但是,当从BackgroundWorker通过buttonBusyWorkerThread_Click调用时,它会加载到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(); } }  电脑屏幕的中心。我该如何解决这个问题?

{{1}}

2 个答案:

答案 0 :(得分:1)

不要从非ui线程调用它。任何基于Windows的UI 101:只有创建线程才能更改对象。

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

答案 1 :(得分:1)

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