1. 程式人生 > >DockPanel的使用與技巧

DockPanel的使用與技巧

個人 part images visible bsp foreach using 大致 會計

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的使用與技巧