DockPanel的基本使用 我就不说了,网上不少,我想说的是在使用DockPanel时 须要注意的几个小问题ide
第一个:函数
使用过DockPanel的人,都有可能会遇到这样一个错误:this
Invalid Content: ActiveContent must be one of the visible contents, or null if there is no visible content.翻译
翻译过来的意思大体是:无效的内容: 若是没有一个可见的内容,ActiveContent必须是可见的内容或空。调试
具体是什么缘由,你们能够相互探讨下。下面我说说出现这个问题的几种状况orm
代码中的this关键字表明的就是Dockpanel所在的窗体为Form1对象
1)、当Dockpanel的DocumentStyle不为DockingMdi时,如下代码会出现这个问题 blog
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
四个小问题,也算不上技巧,是我在开发中遇到过的,里面的原因可能解释不是很清楚,忘你们相互探讨,共同进步。