孟伟斯.NET

快乐的开发者

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在使用OpenExpressApp框架工作中,我们将开源的AvalonDock控件作为界面布局来应用。

AvalonDock是在codeplex上的一个开源项目,专门用于WPF的界面布局,可以做成类似visual studio这样的界面,个人感觉是相当不错的,而且简单易用。 像下面这样的界面用AvalonDock很快就能做出来:

 

 

有兴趣的话,大家可以去codeplex上下载源代码和例子, 相信很快就能学会。但是本文的重点不在这里,我要说的是在使用AvalonDock时遇到的一个问题。先来看下需求吧,其实很简单,我就是想点击一个按钮能弹出泊靠在底部的DockablePane。效果如下:

 点击前:

 

点击后:

 

我的代码如下,XAML:

代码
<Grid>
        
<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文件:

代码
private void btn1_Click(object sender, RoutedEventArgs e)
{
      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方法的末尾是这样写的:

代码
if (content.ActualWidth == 0.0 && (
       dockParent.Anchor 
== AnchorStyle.Left || dockParent.Anchor == AnchorStyle.Right))
{
       ResizingPanel.SetResizeWidth(dockParent, 
new GridLength(200));
       ResizingPanel.SetEffectiveSize(dockParent, 
new Size(2000.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(2000.0));
}

相信大家一眼就能看出来,if语句中的两个条件完全一样,而且执行的语句块也是一摸一样。问题就出在这里,AnchorStyle枚举总共有5个值(Top,Bottom,None,Left,Right),我调用的是一个参数的Show方法,默认的AnchorStyle是AnchorStyle.None,而且我的需求是底部,就算给也应该是AnchorStyle.Bottom。所以说修改如下:

代码
DockablePane dockParent = content.ContainerPane as DockablePane;
dockParent.Anchor 
= desideredAnchor;
if (content.ActualWidth == 0.0 && (dockParent.Anchor!=AnchorStyle.None))
{
       ResizingPanel.SetResizeWidth(dockParent, 
new GridLength(200));
       ResizingPanel.SetEffectiveSize(dockParent, 
new Size(2000.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,我再好好琢磨一下,希望能看到本质,这里先把这个问题提出来,我研究完了再来跟大家分享,大家有兴趣的话一起研究下~

posted on 2009-12-14 18:08  孟伟斯.NET  阅读(7385)  评论(7编辑  收藏  举报