DockPanel的使用與技巧
DockPanel的使用
1.建立一個WinForm工程,默認生成了一個WinForm窗體Form1。
2.引用—>添加引用—>瀏覽—>weiFenLuo.winFormsUI.Docking.dll。
3.設置Form1窗體屬性IsMdiContainer:True。
4.工具箱—>右鍵—>選擇項—>.net組件—>瀏覽—>weiFenLuo.winFormsUI.Docking.dll—>在工具箱出現dockPanel。
( 下載地址:http://sourceforge.net/projects/dockpanelsuite/)
5.將dockPanel拖到窗體Form1上,設置Dock屬性,我設置的是:Fill。
停靠窗體:
1.新建一個WinForm窗體Form2。
2.在代碼中修改窗體繼承於DockContent。
using WeifenLuo.WinFormsUI.Docking;
public partial class Form2 : DockContent
3.在主窗體Form1中顯示停靠窗體。
private void Form1_Load(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show(this.dockPanel1);
}
如果dockPanel嵌套在另1個容器控件上(如:panel),將dockPanel屬性DocumentStyle設置為:
DockingWindow:都顯示為標簽窗體
DockingSdi:主窗體下只打開一個子窗體時是不以標簽窗體的模式展現的,當子窗體的個數>1時才展示為標簽窗體
在使用DockPanel時 需要註意的幾個小問題
第一個:
使用過DockPanel的人,都有可能會遇到這樣一個錯誤:
Invalid Content: ActiveContent must be one of the visible contents, or null if there is no visible content.
翻譯過來的意思大致是:無效的內容: 如果沒有一個可見的內容,ActiveContent必須是可見的內容或空。
具體是什麽原因,大家可以相互探討下。下面我說說出現這個問題的幾種情況
代碼中的this關鍵字代表的就是Dockpanel所在的窗體為Form1
1)、當Dockpanel的DocumentStyle不為DockingMdi時,以下代碼會出現這個問題
Frm_A frmA = null;
//判斷子窗體中是否已經存在在DockPanel中
foreach (DockContent frm in this.dockPanel1.Contents)
{
if (frm is Frm_A)
{
frm.Activate(); //激活子窗體
return;
}
}
frmA = new Frm_A();
frmA.MdiParent = this;
frmA.Show(this.dockPanel1);
解決方案:看你設置Dockpanel的DocumnetStyle是否為DockingMdi。大家也可以試試其他幾種方式(DockingWindow,DockingSdi,SystemMdi)
2)、設置了Dockpanel的DocumentStyle不為DockingMdi時,如果你想要設置窗體Frm_B為左邊浮動窗體,需要設置窗體Frm_B的DockAreas為且僅為DockLeft,如果想要實現其他功能可自行去設置其他屬性信息,現在請看下面代碼
Frm_B frmB = null;
//判斷子窗體中是否已經存在在DockPanel中
foreach (DockContent frm in this.dockPanel1.Contents)
{
if (frm is Frm_B)
{
frm.Activate(); //激活子窗體
return;
}
}
frmB = new Frm_B();
//frmB.MdiParent = this;
frmB.Show(this.dockPanel1,DockState.DockLeft);
註意,如果你在你的代碼中加了紅色註釋的代碼,那麽程序運行時 也會報上面的那個錯
解決方案:註釋紅色的代碼。
原因:(個人理解)frmB.Show(this.dockPanel1,DockState.DockLeft);這句代碼其實就設置了frmB只停靠在DockPanel左邊,此時的frmB是不屬於MDI子窗體的,所以一旦你加入紅色的代碼,程序就會報錯。
第二個:
拖動、停靠、固定子窗體(顯示在Dockpanel中)
拖動:如果你想使你的子窗體可以任意拖動,那麽你在設置子窗體的DockAreas屬性時,保持默認值,不要修改。
停靠:首先你需設置DockAreas的位置,可以停靠在左、右、下等,也可以通過程序代碼控制,參考上面代碼。
固定:只需設置你窗體的DockAreas為Document就行了
第三個:
子窗體和Contents的判斷
很多時候你需要判斷Dockpanel中存在多少個子窗體或Contents,請參考下面代碼:
foreach(Form in this.MdiChildren)
{
//這樣判斷時,停靠的窗體是不會計算在內的
}
而
foreach (DockContent frm in this.dockPanel1.Contents)
{
//這樣設置後,所有的繼承與DockContent的窗體都會被計算在內的
}
第四個:
尋找主窗體、動態顯示子窗體
參考圖:
實現的功能:這裏我們需要實現,右鍵點擊A窗體,通過右鍵菜單來顯示窗體B。
//主窗體的對象
Form1 form1;
private void showB_Click(object senders, EventArgs e)
{
GetFrmMain(); //通過此函數來獲取form1
foreach (Form frm in form1.MdiChildren)
{
if (frm is Frm_B)
{
frm.Activate();
return;
}
}
Frm_B frmB = new Frm_B(this);
frmB.MdiParent = form1;
frmB.Show(form1.dockPanel1);
}
private void GetFrmMain()
{
if (this.Parent.Parent.Parent.Parent != null)
{
form1 = (Form1)this.Parent.Parent.Parent.Parent;
}
else
{
form1 = (Form1)this.Parent.Parent.Parent;
}
}
現在是在A窗體中,this關鍵字已經代碼的不是主窗體了,那麽這裏我們就需要獲取主窗體對象
當A窗體停靠時,需要this.Parent.Parent.Parent.Parent(四個)
不停靠時,只需要三個this.Parent.Parent.Parent
調試代碼發現:停靠時
this.Parent 為 {WeifenLuo.WinFormsUI.Docking.DockPane}
this.Parent.Parent 為 {WeifenLuo.WinFormsUI.Docking.DockWindow, BorderStyle: System.Windows.Forms.BorderStyle.None}
this.Parent.Parent.Parent 為 {WeifenLuo.WinFormsUI.Docking.DockPanel, BorderStyle: System.Windows.Forms.BorderStyle.None}
this.Parent.Parent.Parent 為 {TestEvenhandler.Form1, Text: Form1} 就是我們要找的主窗體Form1
不停靠時:
this.Parent 為 {WeifenLuo.WinFormsUI.Docking.DockPane}
this.Parent.Parent 為 {WeifenLuo.WinFormsUI.Docking.DockPanel+AutoHideWindowControl, BorderStyle: System.Windows.Forms.BorderStyle.None}
this.Parent.Parent.Parent 為 {TestEvenhandler.Form1, Text: Form1} 就是我們要找的主窗體Form1
四個小問題,也算不上技巧,在開發中可能會遇到,忘大家相互探討,共同進步。
DockPanel的使用與技巧