Window Presentation Foundation系列(3)---布局系统简介

      声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。

      本文链接:http://blog.csdn.net/li_007/archive/2011/06/27/6574006.aspx

      开拓进取的小乌龟------->cnBlogs 点滴点点滴滴 Blog

 

      布局系统是WPF中非常重要的一部分知识,也是WPF的精华,很多时候决定了软件的成败。好的布局牵涉到程序的性能,复杂度,耦合度等等。好的布局为广大的程序员提供了充分的控制。

      为了布局的方便,WPF为我们提供了如下几种布局面板。

面板名称

说明

Canvas

定义一个区域,在此区域内,您可以使用相对于 Canvas 区域的坐标显式定位子元素。

DockPanel

定义一个区域,在此区域中,您可以使子元素互相水平或垂直排列。

Grid

定义由行和列组成的灵活的网格区域。

StackPanel

将子元素排列成一行(可沿水平或垂直方向)。

VirtualizingPanel

为虚拟化其子数据集合的 Panel 元素提供一个框架。 这是一个抽象类。

WrapPanel

从左至右按顺序位置定位子元素,在包含框的边缘处将内容断开至下一行。 后续排序按照从上至下或从右至左的顺序进行,具体取决于 Orientation 属性的值。

   
      通常情况下,面板是没有外观的,但是可以通过设置它的background属性,来让它成为可见的对象。特别是当Canvas这样的面板相应子元素鼠标事件的时候。
   
      WPF的布局面板,都是继承自System.Windows.Controls.Panel这个基类的,他们简单的Class Diagram图如下:
基类Panel的继承关系图如下:

      任何一个Panel它都有一些基本的常见公共属性,如Margin,Padding,FlowDirection,ZIndex,RenderTransform和LayoutTransform。他们有不同的功能,决定不同的Panel的作用。

      一个Panel的呈现是分测量和排列这两个阶段来进行的,然后再在屏幕上进行绘制。首先需要询问面板需要多大的空间,在这个过程中需要测量每一个子元素并得到它们所需要的空间,然后来汇总这些数据,从而求出面板所需要的空间。但往往并不是测量了之后就可以确定所需大小的,必须在排列阶段才能获知我们究竟需要多大的空间,因为这涉及到把子元素布局在什么位置,并尽可能地嵌入到有效空间中问题。

      由上面的描述可知,这两个步骤都需要对子元素进行一系列的计算,所以子元素越多,执行计算的次数也就越多,所消耗的资源也就越多。故我们在进行布局的时候,应该尽可能地避免使用不需要的复杂的布局面板,例如如果能够使用Canvas,UniformPanel来进行布局的,就没必要使用Grid这样的复杂的布局面板。同样如果有可能,在我们使用Panel的过程中应该尽可能避免不必要地调用UpdateLayout方法。

     当一个布局发生改变的时候,布局系统都会触发一次新的处理过程,进行重新布局。所以了解那些函数调用,会在什么情况下导致布局系统重新布局,对于优化程序性能很重要,毕竟布局过程是一个递归的过程。

     下面对集中常见的布局面板,进行简单的分析。

 

(1) Canvas

      Canvs是比较简单的布局容器,它能够让我们完全控制每个元素的精确位置。实际情况是Canvas不做任何布局,它只需要简单地把元素放在所指定的位置就算完成布局,而且它默认不会改变元素的大小来填充可用的布局空间,也就意味着Canvas中的子元素是根据元素的内容来调整尺寸大小(注:如果想修剪内容进行布局,可以将ClipToBounds设置为True)。

 名称说明
公共附加属性 Bottom 获取或设置一个值,该值表示某元素的下边缘与其父 Canvas 的下边缘之间的距离。
公共附加属性 Left 获取或设置一个值,该值表示某元素的左边缘与其父 Canvas 的左边缘之间的距离。
公共附加属性 Right 获取或设置一个值,该值表示某元素的右边缘与其父 Canvas 的右边缘之间的距离。
公共附加属性 Top 获取或设置一个值,该值表示某元素的上边缘与其父 Canvas 的上边缘之间的距离。
      如上所示,Canvas利用四个附加属性,来进行子元素位置的指定。通过buttom和Right或者Top和Left两组中的任何一组来指定。往往在一方面比较突出,也就意味着在另一方面,必定受限一些。Canvas提供了精确的控制的代价是缺乏灵活性,使得Canvas不会自动变换大小,需要借助别的Panel来实现灵活的性功能。
      具体事例源码如下:
    1:      "Transparent" Name="layoutCanvas"
   2:              MouseMove="OnDragMeMouseMoveEventHandler" >
   3:          
   4:          "200" Height="100" Canvas.Left="40" Canvas.Top="40">
   5:              
   6:                  "0,0" EndPoint="1,1">
   7:                      "Yellow" Offset="0.0" />
   8:                      "Red" Offset="0.25" />
   9:                      "Blue" Offset="0.75" />
  10:                      "LimeGreen" Offset="1.0" />
  11:                  
  12:              
  13:          
  14:   
  15:   
  16:          
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
   9:              
   
   

 

    运行结果如下截图:

(3) StackPanel

      StackPanel也是一个简单的布局面板,它将子元素按一行或者一列进行排列。但是同样它的功能不足以进行整个面板的布局,而是进行一些的模块的布局。默认情况下,它是横排(Horizontal),但是也可以通过设置Orientation为Vertical进行竖排布局。再默认横排情况下,每个子元素跟面板一样宽,反之竖排亦然。当子元素超过了面板空间的时候,它会自动截断多出的内容。

      当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment 和VerticalAlignment属性来决定如何分配。
      简单的示例代码如下:
   1:      "Gainsboro">
   2:          "3">Look For:
   3:          "3" SelectedIndex="0">
   4:              Math
   5:              English
   6:              History
   7:              Physics
   8:          
   9:          "3">Filter By:
  10:          "3">
  11:          
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
   9:              
   
   

 

    运行结果如下截图:

(3) StackPanel

      StackPanel也是一个简单的布局面板,它将子元素按一行或者一列进行排列。但是同样它的功能不足以进行整个面板的布局,而是进行一些的模块的布局。默认情况下,它是横排(Horizontal),但是也可以通过设置Orientation为Vertical进行竖排布局。再默认横排情况下,每个子元素跟面板一样宽,反之竖排亦然。当子元素超过了面板空间的时候,它会自动截断多出的内容。

      当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment 和VerticalAlignment属性来决定如何分配。
      简单的示例代码如下:
   1:      "Gainsboro">
   2:          "3">Look For:
   3:          "3" SelectedIndex="0">
   4:              Math
   5:              English
   6:              History
   7:              Physics
   8:          
   9:          "3">Filter By:
  10:          "3">
  11:          
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
   9:              
   
   

 

    运行结果如下截图:

(3) StackPanel

      StackPanel也是一个简单的布局面板,它将子元素按一行或者一列进行排列。但是同样它的功能不足以进行整个面板的布局,而是进行一些的模块的布局。默认情况下,它是横排(Horizontal),但是也可以通过设置Orientation为Vertical进行竖排布局。再默认横排情况下,每个子元素跟面板一样宽,反之竖排亦然。当子元素超过了面板空间的时候,它会自动截断多出的内容。

      当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment 和VerticalAlignment属性来决定如何分配。
      简单的示例代码如下:
   1:      "Gainsboro">
   2:          "3">Look For:
   3:          "3" SelectedIndex="0">
   4:              Math
   5:              English
   6:              History
   7:              Physics
   8:          
   9:          "3">Filter By:
  10:          "3">
  11:          

   
   
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
  12:          "3">Search in titles only
  13:          "3">Match related words
  14:          "3">Search in previous results
  15:          "3">Highlight search hits (in topics)
  16:   
  17:          
  18:          
  19:          
  20:          
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      

   

     运行结果截图如下:

(4) WrapPanel

      WrapPanel的功能跟StackPanel基本上没有区别,不同的是,当子元素的空间超过了面板的时候,StackPanel是进行截断,而WrapPanel则是会将元素重启一行,进行排列。同样它也提供了Horizontal和Vertical两种方式供Orientation选择。

      简单的实例代码如下:

   1:      "LightPink" Orientation="Horizontal" Name="wrapPanelLayout">
   2:          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值