介绍:

        借助AvalonDock可以开发出类似于VS2010的软件界面,实现可停靠布局。

使用时需要Nugit中下载Extended.wpf.toolkit插件.

Xaml中需要应用命名空间

xmlns:avalon="http://schemas.xceed.com/wpf/xaml/avalondock"

下图是AvalonDock主页展示的示例截图。

AvalonDock截图


AvalonDock库提供了一些基本的类。

  • DockingManger:管理停靠类。DockingManger中只允许包含一个LayoutRoot类
  • DockingMange.Theme:用于设置AvalonDock的布局主题。        主题主要包含如下四种主题:VS2010Theme、AeroTheme、GenericTheme、MetroTheme。
  • LayoutRoot:布局根节点类。LayoutRoot下只可以有一个LayoutPanel
  • LayoutPanel:布局面板类。 LayoutPanel下可以嵌套一个LayoutPanel
  • LayoutAnchorablePane:可停靠窗格类。
  • LayoutDocumentPane:文档窗格类。
  • LayoutAnchorablePaneGroup:可停靠窗格组类。
  • LayoutDocumentPaneGroup:文档窗格组类。
  • LayoutAnchorable:可停靠内容类。
  • LayoutDocument:文档内容类。
  • DockingManager作为顶层容器,然后包含一个LayoutRoot对象,LayoutRoot中又包含一个LayoutPanel对象。LayoutPanel中便是LayoutAnchroablePane对象和LayouDocumentPane对象的集合。同时,可以对LayoutAnchroablePane对象和LayouDocumentPane对象进行分组,每个组可以单独设定组内的浮动方向。LayoutAnchorablePane又是LayoutAnchorable的容器,LayioutDocumanePane又是LayoutDocument的容器。一层一层进行嵌套,在最后的LayoutAnchorable中或者LayoutDocument中,我们放入我们真正的控件对象,这样,就可以对他们进行分类摆放布局。

可以在layoutroot下可以增加多个Layout.Root.Leftside、 Layout.Root.Rightside、Layout.Root.BottomSide、

AvalonDocking提供了格式的保存和恢复。

下面介绍具体的用法。

1.窗体布局存储与恢复

DockingManager中提供了将窗体布局序列化为xml文件内容的方法,同时提供了从xml布局文件中恢复布局的方法。

(1)保存布局

XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockManager);
 using (var stream = new StreamWriter("Layout.xml"))
 {
         serializer.Serialize(stream);
}

(2)恢复布局

XmlLayoutSerializer serializer = new XmlLayoutSerializer(DockManager);
 using (var stream = new StreamReader("Layout.xml"))
{
     serializer.Deserialize(stream);
 }

恢复布局时,有一点需要注意,需要为LayoutAnchrobale对象和LayoutDocument对象设置ContentId属性,否则,DockingManager会忽略内容的恢复。

2.主题更换

AvalonDock中提供了六种主题样式,要使用这些主题,需要在程序中导入主题库。DockManger为DockingManager对象,通过改变DockingManager中的Theme属性,便可以改变整个界面的样式。

DockManager.Theme = new GenericTheme();
//DockManager.Theme = new AeroTheme();
//DockManager.Theme = new ExpressionDarkTheme();
//DockManager.Theme = new ExpressionLightTheme();
//DockManager.Theme = new MetroTheme();
//DockManager.Theme = new VS2010Theme();

3.RootSide操作

动态改变LayoutRoot.LeftSide对象内容。

(1)xaml中的代码

<avalon:LayoutRoot.LeftSide>
       <avalon:LayoutAnchorSide>
                <avalon:LayoutAnchorGroup x:Name="LeftGroup">
                                
                  </avalon:LayoutAnchorGroup>
       </avalon:LayoutAnchorSide>
</avalon:LayoutRoot.LeftSide>

(2)后台代码

private void miLeft_Click_1(object sender, RoutedEventArgs e)
 {
            try
            {
                LayoutAnchorable anchorable = new LayoutAnchorable();
                anchorable.Title = "Left";
                LeftGroup.Children.Add(anchorable);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "[MainWindow][miLeft_Click_1]");
            }
 }

4.Pane操作

动态改变软件中的窗格布局。

(1)xaml中的代码

<avalon:DockingManager x:Name="DockManager">
                <avalon:DockingManager.Theme>
                    <avalon:ExpressionDarkTheme/>
                </avalon:DockingManager.Theme>
                
                <avalon:LayoutRoot x:Name="Root">
                    <avalon:LayoutPanel x:Name="Panel" >
                        <avalon:LayoutAnchorablePaneGroup x:Name="LeftAnchorableGroup" DockWidth="300">
                            <avalon:LayoutAnchorablePane x:Name="LeftPane">
                                <avalon:LayoutAnchorable x:Name="Solution" Title="解决方案" ContentId="Solution"/>
                            </avalon:LayoutAnchorablePane>
                        </avalon:LayoutAnchorablePaneGroup>
                        
                        <avalon:LayoutAnchorablePane>
                            <avalon:LayoutAnchorable ></avalon:LayoutAnchorable>
                        </avalon:LayoutAnchorablePane>
                        <avalon:LayoutDocumentPane>
                            <avalon:LayoutDocument></avalon:LayoutDocument>
                        </avalon:LayoutDocumentPane>
                        
                        <avalon:LayoutDocumentPaneGroup x:Name="DocumentGroup">
                            <avalon:LayoutDocumentPane x:Name="DocumentPane">
                                <avalon:LayoutDocument Title="document" ContentId="document">
                                    
                                </avalon:LayoutDocument>
                            </avalon:LayoutDocumentPane>
                        </avalon:LayoutDocumentPaneGroup>
                        
                        <avalon:LayoutAnchorablePaneGroup x:Name="RightAnchorableGroup" Orientation="Vertical" DockWidth="300">
                            <avalon:LayoutAnchorablePane x:Name="RightPane" >
                                <avalon:LayoutAnchorable Title="属性" ContentId="Property"/>
                            </avalon:LayoutAnchorablePane>
                        </avalon:LayoutAnchorablePaneGroup>
                        
                        
                    </avalon:LayoutPanel>
    </avalon:LayoutRoot>
 </avalon:DockingManager>

(2)添加水平AnchorablePane

private void miAnchorPane_Click_1(object sender, RoutedEventArgs e)
 {
            try
            {
                LayoutAnchorablePane pane = new LayoutAnchorablePane();
                LayoutAnchorable anchorable = new LayoutAnchorable();
                anchorable.Title="水平方向";
                pane.Children.Add(anchorable);
                LeftAnchorableGroup.Children.Add(pane);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message,"[MainWindow][miAnchorPane_Click_1]");
            }
          
 }

(3)添加竖直AnchorablePane

private void miAnchorVerticalPane_Click_1(object sender, RoutedEventArgs e)
{
           try
            {
                LayoutAnchorablePane pane = new LayoutAnchorablePane();
                LayoutAnchorable anchorable = new LayoutAnchorable();
                anchorable.Title = "竖直方向";
                pane.Children.Add(anchorable);
                RightAnchorableGroup.Children.Add(pane);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "[MainWindow][miAnchorVerticalPane_Click_1]");
            }
 }

(4)添加DocumentPane

private void miDocumentPane_Click_1(object sender, RoutedEventArgs e)
 {
            try
            {
                LayoutDocumentPane documentPane = new LayoutDocumentPane();
                LayoutDocument document = new LayoutDocument();
                document.Title = "document";
                document.Content = new RichTextBox();
                documentPane.Children.Add(document);
                DocumentGroup.Children.Add(documentPane);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "[MainWindow][miDocumentPane_Click_1]");
            }
 }

5.浮动窗体显示

private void miSearchWnd_Click_1(object sender, RoutedEventArgs e)
 {
            LayoutAnchorable anchorable = new LayoutAnchorable();
            anchorable.Title = "查询";
            anchorable.FloatingWidth = 300;
            anchorable.FloatingHeight = 300;
            anchorable.FloatingTop = 200;
            anchorable.FloatingLeft = 300;

            Button button = new Button();
            button.Content = "查询";
            button.Width = 80;
            button.Height = 40;

            anchorable.Content = button;
            LeftPane.Children.Add(anchorable);
            anchorable.Float();     //调用Float方法,使窗体浮动显示
}

6.隐藏窗体显示

private void miRestoreHideWnd_Click_1(object sender, RoutedEventArgs e)
{
            try
            {
                if (Root.Hidden != null)
                {
                    while (Root.Hidden.Count > 0)
                    {
                        Root.Hidden[0].Show();//调用show方法,恢复窗体显示。
                    }
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message, "[MainWindow][miRestoreHideWnd_Click_1]");
            }
}

7.窗体操作

(1)添加Anchorable

private void miAddAnchroable_Click_1(object sender, RoutedEventArgs e)
 {
            LayoutAnchorable anchorable = new LayoutAnchorable();
            anchorable.Title = "工具";
            Button btn = new Button();
            btn.Content = "this is a test button";
            anchorable.Content = btn;
            btn.Height = 30;
            btn.Width = 150;
            anchorable.IsActive = true;
            RightPane.Children.Add(anchorable);
}

(2)添加Document

private void miAddDocument_Click_1(object sender, RoutedEventArgs e)
{
            LayoutDocument document = new LayoutDocument();
            document.Title = "doc";
            document.Content = new RichTextBox();
            document.IsActive = true;
            DocumentPane.Children.Add(document);
}

(3)添加并显示窗体

private void miOutPutWnd_Click_1(object sender, RoutedEventArgs e)
{
            LayoutAnchorable anchorable = new LayoutAnchorable();
            anchorable.Title = "输出";
            anchorable.Content = new RichTextBox();
            anchorable.AddToLayout(DockManager, AnchorableShowStrategy.Bottom);
}

(4)窗体切换自动隐藏

private void miAutoHide_Click_1(object sender, RoutedEventArgs e)
 {
            if (Solution != null)
            {
                Solution.ToggleAutoHide();
            }
 }

去掉标题行的钉子

在这里插入图片描述
在LayoutAnchorable上添加属性:

CanAutoHide="False" CanClose="False"

如果要去掉X,再添加

CanHide="False"