2014-03-12 30 views
-1

當通過buttonBusy_ClickformWaitingForm在主窗體的中心 中按預期的方式從UI線程調用FormWaitingForm時,在下面的代碼上。但是,當從BackgroundWorker通過buttonBusyWorkerThread_Click調用時,它會加載到PC屏幕的中心 中。我怎樣才能解決這個問題 ?當從BackgroundWorker調用時,中心父級不起作用

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

@OP你創建多個線程的用戶界面。不要這樣做。在整個應用程序中使用單個UI線程。另外,不要通過調用其中的'Thread.Sleep'來阻止你的UI線程。 – Servy

+0

@Servy我無法從我的實際應用程序的主線程中啓動,因爲我有一個可以觸發我的應用程序來執行工作的filsystemwatcher - 正是那種需要顯示我的繁忙表單的方法(不在主UI中運行)。上面的例子只是一個簡單的表示。有任何想法嗎 ? – user1438082

+0

當你想從非UI線程更新UI時,你總是這樣做。網上有數以百萬計的資源描述瞭如何處理這種情況。 – Servy

回答

1

FormStartPosition.CenterParent適用於母公司的MDI表格,不適用於所有者的形式。因此它不會影響非MDI表格。

您可以使用這些擴展方法來打開窗體centerd它的主人形式:

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

不要從非UI線程調用它。任何基於Windows的UI 101:只有創建線程才能更改該對象。

在後臺線程中,使用Invoke調用回UI線程。

相關問題