CenterParent 窗體在其父窗體中居中。
CenterScreen 窗體在當前顯示窗口中居中,其尺寸在窗體大小中指定。
Manual 窗體的位置由 Location 屬性確定。
WindowsDefaultBounds 窗體定位在 Windows 默認位置,其邊界也由 Windows 默認決定。
WindowsDefaultLocation 窗體定位在 Windows 默認位置,其尺寸在窗體大小中指定。
也就是說,CenterScreen的意思並不是屏幕居中(是相對的),它是在"當前顯示窗口"中居中,當用Show()方法時應選擇CenterScreen,用ShowDialog()方法時應選擇CenterParent,這樣才能讓要顯示的窗口居中。
在SDI中用ShowDialog()方法,並且設置對應的窗體的StartPosition為CenterParent時就可以讓窗體居中,當然也可以用CenterScreen也是一樣的效果,只是含意不一樣罷了.
而在MDI中只能用Show(),如果你用ShowDialog(),無論選擇CenterParent或是CenterScreen都會出錯,說ShowDialog只能用在頂級窗口之類的意思。用Show(),並且設置對應的窗體的StartPosition為CenterScreen時就可以讓窗體居中。
ShowDialog() 彈出模式化的窗體
Show() 彈出非模式化的窗體
模式窗體,在關閉或隱藏前無法切換到主窗體。
非模式窗體,變換焦點使不必關閉窗體
總結:顯示重要的信息,還是用模式窗體,如刪除文件,可以確保用戶正真想要刪除的是該文件
非模式的,窗體訪問的順序沒有辦法得知,比較適合顯示程序的一些相關信息。
Application.Run()是"Begins running a standard application message loop on the current thread, and makes the specified form visible." 用代碼可以表示為:
while(GetMessage(&msg)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
執導受到WM_QUIT,退出應用程序。而使用Form.Show()方法則Form顯示后就立刻退出程序。如果用Form.ShowDialog()是模化對話框所以不會立刻消失,但是如果您還有其他窗口,Form.ShowDialog()顯示的是模態窗口,只有它退出,其他窗口才能顯示,但是一旦退出整個程序就退出,其他窗口將永不會得到運行機會,而用Application.Run()就不會出現這種現象。
窗體顯示中form1.Show()和form1.ShowDialog()的區別
窗體和對話框要么是有模式的,要么是無模式的。“模式”窗體或對話框必須關閉或隱藏,然后您才能繼續使用應用程序的其余部分。
顯示重要消息的對話框應始終是有模式的。模式對話框的一個示例是 Visual Studio 中的“關於”對話框。MessageBox是您可以使用的一個模式窗體。有模式對話框顯示出來以后,那么開始打開的窗體或對話框就不能再獲得焦點了。
“無模式”窗體讓您在此窗體與另一窗體之間變換焦點,而不必關閉初始窗體。用戶在該窗體顯示的同時可繼續在任何應用程序的其他位置工作。例如:文本編輯軟件里面的搜索功能,就是一個無模式的,因為搜索對話框出來以后,還可以操作編輯本文,即它不影響其他窗體獲得焦點。
將窗體顯示為有模式對話框用form1.ShowDialog()方法。這個方法有一個可選參數 owner,該參數可用於指定窗體的父子關系。例如:
在Form1代碼段中:
Form2 f2=new Form2();
f2.ShowDialog(this);//this表示Form1當前實例
這樣f2實例就和Form1實例建立了一個父子關系,可以相互通訊。
如果沒有使用f2.ShowDialog(this)而直接使用的是無參的,要定義父子關系,則需要語句f2.owner=this;
將窗體顯示為無模式對話框則用form1.Show()方法。
注意 如果窗體顯示為有模式,則在關閉該對話框之前,不執行 ShowDialog 方法后面的代碼。但是,當窗體顯示為無模式時,那么該窗體顯示之后,會立刻執行 Show 方法后面的代碼。
窗體的Show方法,沒有給調用代碼任何通知,如果需要通知,使用ShowDialog是一種好的選擇。
在調用Show方法后,Show方法后面的代碼會立即執行,調用ShowDialog方法后,調用代碼被暫停執行,等到調用ShowDialog方法的窗體關系后再繼續執行。而且窗體可以返回一個dialogresult值,他描述了窗體關閉的原因,例如OK,Cancel,yes,no等。為了讓窗體返回一個dialogresult,必須設置窗體的dialogresult值,或者在窗體的一個按鈕上設置dialogresult屬性。
例子:
下面是子窗體代碼,要求輸入phone,然后會返回給父窗體。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Phone : Form
{
public Phone()
{
InitializeComponent();
btnOK.DialogResult = DialogResult.OK;
btnOK.DialogResult = DialogResult.Cancel;
}
public string PhoneNumber
{
get { return textBox1.Text; }
set { textBox1.Text = value; }
}
private void Phone_Load(object sender, EventArgs e)
{
}
}
}
不包含任何處理按鈕單擊事件的代碼,因為設置了每個按鈕的dialogresult屬性,所以單擊OK或者Cancel按鈕后,窗體就消失了。下面的代碼顯示了父窗體中調用Phone對話框的方法。
Form.Show和Form.ShowDialog的區別
區別1:ShowDialog是模態的(獨占用戶輸入),Show是非模態的。
區別2:根據1,ShowDialog只能打開一個自己,Show可以打開多個自己。
區別3:根據2,使用Show方法打開的Form在關閉時會立即調用Dispose釋放資源。那ShowDialog會在關閉時立即釋放資源嗎?我做了個實驗。
public partial class Form1 : Form
{
private Form2 f2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
f2.Show();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
f2.ShowDialog();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void button3_Click(object sender, EventArgs e)
{
f2 = new Form2();
}
}
連續點擊button1會提示“無法訪問已釋放的對象。對象名:Form2”。而連續點擊button2則不然,一切正常。繼續調查發現,使用ShowDialog時,第一次會調用構造函數Form2(),然后依次調用Form2_Load,Form2_Activated,Form2_Shown。第二次及以后使用ShowDialog時,只會調用Form2_Load,Form2_Activated,Form2_Shown。由此可以判斷,Form2在關閉時只是被隱藏,而非解構。
ShowDialog的這種設計也是有道理的,在連續調用時可以節省資源,但也要警惕"上輩子"影響到"這輩子"。如果想及時釋放資源,在調用Form.ShowDialog()后面不妨加一句Form.Close(),Close方法會調用Dispose解構Form。