原文:AvalonDock的基本用法

        AvalonDock是优秀的开源项目,用于创建可停靠式布局,能够在WPF中方便开发出类似VS2010的软件界面。对于复杂的软件系统,大量控件的使用会使的界面变得难以管理。AvalonDock帮我们解决了这一问题。想要在WPF项目中使用AvalonDock的功能,首先要加载AvalonDock所提供的动态库,下载地址:http://avalondock.codeplex.com/releases/view/107371,目前最新的库版本为2.02。下载AvalonDock的动态库与主题库,解压后如图所示:

在WPF项目的引用中添加这些库,然后使用在xaml中引入命名空间:xmlns:avalon="http://schemas.xceed.com/wpf/xaml/avalondock",便可以在WPF中开发AvalonDock应用程序了。

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

AvalonDock库中提供了一些基本的类,熟悉这些类的功能是使用AvalonDock的第一步。

DockingManager : 停靠管理器类,是AvalonDock中的核心控件之一,负责管理浮动窗体、布局存储、恢复,样式主题等。在XAML中,是AvaDock元素的根节点。

LayoutRoot : 布局根节点类,DockingManager中的内容控件完全占满DockingManager中的空间。LayoutRoot包含四个属性,LeftSide,RightSide,TopSide,BottomSide,分别用于展示DockingManager中左右上下四个位置的内容,但初始状态为隐藏状态。另外两个属性FloatingWindows,Hidden分别为浮动窗体集合和隐藏窗体集合。当一个窗格浮动时,AvalonDock会将其从其所在组中删除,然后放置到FloatingWindows集合中。当一个窗格关闭时,会将其放置在Hidden集合中。

LayoutPanel:布局面板类,LayoutRoot中的内容控件,完全占满LayoutRoot中的空间,在LayoutPanel中,可以有多个LayoutGroup,可以设定Orientation 属性,控件布局组的浮动方向。实际的窗格都位于LayoutPanel节点下。

LayoutAnchorablePane:可停靠窗格类,浮动窗格是可停靠控件LayoutAnchorable的容器。一个窗格中,可以有多个可停靠控件。浮动窗格中的可停靠控件只能是LayoutAnchorable.窗格大小设定后,不能自动改变。

LayoutDocumentPane:文档窗格类,与LayoutAnchorablePane类似,也是可停靠控件的容器,文档窗格类中可以放置可停靠控件LayoutAnchorable,也可以放置文档控件LayoutDocument,LayoutDocunemtPane会自动占满窗体的窗体布局中的剩余空间。

LayoutAnchorablePaneGroup:可停靠窗格组类,是可停靠窗格LayoutAnchorablePane的容器。通过设置Orientation 属性,用于管理多个可停靠窗格的浮动方向。

LayoutDocumentPaneGroup:文档窗格组类,是文档窗格LayoutDocumentPane的容器。通过设置Orientation 属性,用于管理多个文档窗格的浮动方向。

LayoutAnchorable:可停靠内容类,一般放置在LayoutAnchorablePane中,其内容可以是用户自定义控件类型,比如,在UserControl中设置好WPF基础控件布局,然后将整个UserControl放置在LayoutAnchorable中,这样,整个UserControl内容就可以随着可停靠控件一起浮动或者停靠。

LayoutDocument:文档类,与LayoutAnchorable功能类似,区别在于LayoutDoucument会随着LayoutDocumentPane一起占满窗体剩余空间。

 

        介绍了这么多内容,目的只是为了让大家对AvalonDock中的类有个简单的了解。其实AvalonDock中的类有着明显的层次结构,其实就是容器的嵌套。DockingManager作为顶层容器,然后包含一个LayoutRoot对象,LayoutRoot中又包含一个LayoutPanel对象。LayoutPanel中便是LayoutAnchroablePane对象和LayouDocumentPane对象的集合。同时,可以对LayoutAnchroablePane对象和LayouDocumentPane对象进行分组,每个组可以单独设定组内的浮动方向。LayoutAnchorablePane又是LayoutAnchorable的容器,LayioutDocumanePane又是LayoutDocument的容器。一层一层进行嵌套,在最后的LayoutAnchorable中或者LayoutDocument中,我们放入我们真正的控件对象,这样,就可以对他们进行分类摆放布局。

下面介绍具体的用法。

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();
}
}

至此,AvalonDock的基础用法,至于更改AvalonDock的外观样式,使用MVVM模式等高级的用法,需要自己慢慢去学习了。

完整的源码下载:http://download.csdn.net/detail/tianwenxue/8871487

本文原创,转载请注明出处。

AvalonDock的基本用法的更多相关文章

  1. Docking For WPF–AvalonDock

    桌面程序的应用,不可避免的就会用到大量的布局控件,之前的一个项目也想过去做类似于Visual Studio的那种灵活的布局控件,也就是界面上的控件能够实现拖拽放置.隐藏.窗口化等一系列的操作,但由于开 ...

  2. EditText 基本用法

    title: EditText 基本用法 tags: EditText,编辑框,输入框 --- EditText介绍: EditText 在开发中也是经常用到的控件,也是一个比较必要的组件,可以说它是 ...

  3. jquery插件的用法之cookie 插件

    一.使用cookie 插件 插件官方网站下载地址:http://plugins.jquery.com/cookie/ cookie 插件的用法比较简单,直接粘贴下面代码示例: //生成一个cookie ...

  4. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  5. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  6. python enumerate 用法

    A new built-in function, enumerate() , will make certain loops a bit clearer. enumerate(thing) , whe ...

  7. [转载]Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法总结

    本文对Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法进行了详细的总结,需要的朋友可以参考下,希望对大家有所帮助. 详细解读Jquery各Ajax函数: ...

  8. 【JavaScript】innerHTML、innerText和outerHTML的用法区别

    用法: <div id="test">   <span style="color:red">test1</span> tes ...

  9. chattr用法

    [root@localhost tmp]# umask 0022 一.chattr用法 1.创建空文件attrtest,然后删除,提示无法删除,因为有隐藏文件 [root@localhost tmp] ...

随机推荐

  1. LeetCode解题报告--2Sum, 3Sum, 4Sum, K Sum求和问题总结

    前言: 这几天在做LeetCode 里面有2sum, 3sum(closest), 4sum等问题, 这类问题是典型的递归思路解题.该这类问题的关键在于,在进行求和求解前,要先排序Arrays.sor ...

  2. 【转载】 Searching过程粗略梳理 分类: H4_SOLR/LUCENCE 2014-07-25 22:59 316人阅读 评论(0) 收藏

    转载自:http://www.cnblogs.com/huangfox/archive/2012/02/09/2344686.html solr-searching过程分析(一) --searchin ...

  3. 【solr基础教程之二】索引 分类: H4_SOLR/LUCENCE 2014-07-18 21:06 3331人阅读 评论(0) 收藏

    一.向Solr提交索引的方式 1.使用post.jar进行索引 (1)创建文档xml文件 <add> <doc> <field name="id"&g ...

  4. solr源码导入eclipse 分类: H4_SOLR/LUCENCE 2014-07-14 14:11 550人阅读 评论(1) 收藏

    转载自:http://blog.csdn.net/vltic/article/details/19917377 (1)相应的开发环境准备          (1)jdk1.6+的安装和环境变量配置(命 ...

  5. 【Lucene4.8教程之五】Luke 2014-06-24 15:12 1092人阅读 评论(0) 收藏

    一.Luke基本内容 1.Luke简介 Luke可用于查看Lucene创建的索引,并对其进行基本操作. 2.创建Luke (1)从Github上下载源文件 https://github.com/tar ...

  6. printk()函数的总结

    我们在使用printk()函数中使用日志级别为的是使编程人员在编程过程中自定义地进行信息的输出,更加容易地掌握系统当前的状况.对程序的调试起到了很重要的作用.(下文中的日志级别和控制台日志控制级别是一 ...

  7. 【codeforces 742A】Arpa’s hard exam and Mehrdad’s naive cheat

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  8. 线上java排查

    http://www.oschina.net/question/560995_137855?sort=default&p=3#answers http://www.blogjava.net/h ...

  9. [TypeScript] Create random integers in a given range

    Learn how to create random integers using JavaScript / TypeScript. /** * Returns a random int betwee ...

  10. Redis使用文档一

    1 Redis概述 1.1前言 Redis是一个开源.支持网络.基于内存亦可持久化的日志型.键值对存储数据库.使用ANSI C编写.并提供多种语言的API. 其开发由VMware主持,是最流行的键值对 ...