在使用OpenExpressApp框架工作中,我们将开源的AvalonDock控件作为界面布局来应用。
AvalonDock是在codeplex上的一个开源项目,专门用于WPF的界面布局,可以做成类似visual studio这样的界面,个人感觉是相当不错的,而且简单易用。 像下面这样的界面用AvalonDock很快就能做出来:
有兴趣的话,大家可以去codeplex上下载源代码和例子, 相信很快就能学会。但是本文的重点不在这里,我要说的是在使用AvalonDock时遇到的一个问题。先来看下需求吧,其实很简单,我就是想点击一个按钮能弹出泊靠在底部的DockablePane。效果如下:
点击前:
点击后:
我的代码如下,XAML:
< ad:DockingManager x:Name ="dockManager" >
< ad:ResizingPanel Orientation ="Vertical" >
< ad:ResizingPanel Orientation ="Horizontal" >
< ad:DocumentPane x:Name ="documentsHost" >
< ad:DocumentContent Title ="File1.doc" >
< RichTextBox />
</ ad:DocumentContent >
< ad:DocumentContent Title ="File2.doc" >
< Button x:Name ="btn1" Click ="btn1_Click" Content ="click" Width ="300" Height ="50" ></ Button >
</ ad:DocumentContent >
</ ad:DocumentPane >
</ ad:ResizingPanel >
< ad:DockablePane ad:ResizingPanel.ResizeHeight ="200" x:Name ="pane" />
</ ad:ResizingPanel >
</ ad:DockingManager >
</ Grid >
对应的CS文件:
{
DockableContent dc = new DockableContent();
TextBox tb = new TextBox();
dc.Content = tb;
dc.HideOnClose = true ;
dc.Title = " Test " ;
this .pane.Items.Add(dc);
this .dockManager.Show(dc);
}
写完运行,点击按钮,但是却一点儿反应都没有。更奇怪的是,当我拖动窗体的边框时,DockablePane自己却跳出来了。难道说DockablePane信春哥,原地复活么~
其实玄机就出在Show方法上,打开源代码,发现Show方法的末尾是这样写的:
dockParent.Anchor == AnchorStyle.Left || dockParent.Anchor == AnchorStyle.Right))
{
ResizingPanel.SetResizeWidth(dockParent, new GridLength( 200 ));
ResizingPanel.SetEffectiveSize(dockParent, new Size( 200 , 0.0 ));
}
else if (content.ActualWidth == 0.0 && (
dockParent.Anchor == AnchorStyle.Left || dockParent.Anchor == AnchorStyle.Right))
{
ResizingPanel.SetResizeWidth(dockParent, new GridLength( 200 ));
ResizingPanel.SetEffectiveSize(dockParent, new Size( 200 , 0.0 ));
}
相信大家一眼就能看出来,if语句中的两个条件完全一样,而且执行的语句块也是一摸一样。问题就出在这里,AnchorStyle枚举总共有5个值(Top,Bottom,None,Left,Right),我调用的是一个参数的Show方法,默认的AnchorStyle是AnchorStyle.None,而且我的需求是底部,就算给也应该是AnchorStyle.Bottom。所以说修改如下:
dockParent.Anchor = desideredAnchor;
if (content.ActualWidth == 0.0 && (dockParent.Anchor != AnchorStyle.None))
{
ResizingPanel.SetResizeWidth(dockParent, new GridLength( 200 ));
ResizingPanel.SetEffectiveSize(dockParent, new Size( 200 , 0.0 ));
}
现在点击按钮,DockablePane就如约而至了。但是其实还是有问题,就是我在调用Show方法的时候就要这么this.dockManager.Show(dc,DockableContentState.Docked,AnchorStyle.Bottom);
但是当我改为Top,Left,Right时,期望出现对应的效果,但是最终仍然出现在了底部。而且当我给None的时候,表面上看DockablePane没有弹出来,但是一旦拖动窗体大小,就又出来了。还有ResizingPanel.SetEffectiveSize(dockParent, new Size(200, 0.0));似乎没起到作用,我把它注释掉,依然能弹出DockablePane,我再好好琢磨一下,希望能看到本质,这里先把这个问题提出来,我研究完了再来跟大家分享,大家有兴趣的话一起研究下~