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:          "DragMe" Content="Please, Drag me!" Height="40" Width="120"

       
      
      
      
  17:                  Canvas.Left="80" Canvas.Top="70"
  18:                  MouseLeftButtonDown="OnDragMeMouseDownEventHandler"
  19:                  MouseLeftButtonUp="OnDragMeMouseUpEventHandler"/>
  20:      

        运行结果如下所示:

 

(2) DockPanel

      DockPanel适合于进行简单的整体布局,可以用来划分窗体的基本结构。它总是会对每个元素进行排列,默认情况下最后一个子元素负责填充剩余的布局空间。同样它利用附加属性Dock来指定元素的靠边位置(注:如果你不想最后一个元素填充剩余布局空间,可以将属性LastChildFill设置为False)。

      简单示例代码如下:

   1:      "SkyBlue" Name="dockPanelLayout">
   2:          
"Left" Content="Left" Width="60" />
   3:          
"Right" Content="Right" Width="60"/>
   4:          
"Top" Content="Top" Height="60"/>
   5:          
"Bottom" Content="Bottom" Height="60"/>
   6:          
"Fill" Name="btnChanged" Click="OnClicked" Background="Tomato"/>
   7:          
   8:          
          
         
         
         

          
         
         
         
   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:          
"3, 5">Search
  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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  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:          
"3, 5">Search
  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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
"3, 5">Search
   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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  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:          
"3, 5">Search
  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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      
"3, 5">Search
   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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  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:          "3, 5" HorizontalAlignment="Left">HorizontalAlignment="Left"
  18:          "3, 5" HorizontalAlignment="Center">HorizontalAlignment="Center"
  19:          "3, 5" HorizontalAlignment="Right">HorizontalAlignment="Right"
  20:          "3, 5" HorizontalAlignment="Stretch">HorizontalAlignment="Stretch"
  21:          
  22:          "3,15" Foreground="Red" TextWrapping="Wrap">
  23:              StackPanel有水平(Horizontal)和垂直(Vertical)两种布局
  24:              当一个元素被赋予一个比其内容要大的固定大小的时候,剩余空间将由元素的HorizontalAlignment
  25:              和VerticalAlignment属性来决定如何分配。
  26:          
  27:      

你可能感兴趣的:(Windows,Presentation,Foundation)