WPF 基礎到企業應用系列6——布局全接觸

作者: 圣殿騎士  發布時間: 2010-08-02 12:02  閱讀: 3808 次  推薦: 0   原文鏈接   [收藏]  
 

  一.摘要

  首先很高興這個系列能得到大家的關注和支持,這段時間一直在研究Windows Azure,所以暫緩了更新,同時也本著想把它寫好、寧缺毋濫的精神,在速度上自然也就慢了下來,這篇文章拖拖拉拉也經歷了十多天才發布出來(每天寫一點),不過請大家放心,這個系列一定會繼續寫下去。由于自己才疏學淺且是對這些技術的使用總結和心得體會,錯誤之處在所難免,懷著技術交流的心態,在這里發表出來,所以希望大家能夠多多指點,這樣在使一部分人受益的同時也能糾正我的錯誤觀點,以便和各位共同提高。

  這篇文章主要是對WPF布局系統做一個較簡單的介紹,大家都知道:UI是做好一個軟件很重要的因素,如果沒有一個漂亮的UI,再怎么強大的功能也會顯得這個軟件很脆弱且沒有投資價值。本文以總分總的形式展開介紹:首先對WPF Panel做一個總體認識、然后講解各Panel基本用法、布局綜合應用、自定義布局控件以及最后的總結,希望對大家有所幫助。

  二.本文提綱

· 1.摘要

· 2.本文提綱

· 3.總體介紹

· 4.Canvas

· 5.StackPanel

· 6.WrapPanel

· 7.DockPanel

· 8.Grid

· 9.UniformGrid

· 10.ViewBox

· 11.Border

· 12.ScrollViewer

· 13.布局綜合應用

· 14.自定義布局控件

· 15.本文總結

· 16.系列進度

  三.總體介紹

  WPF的布局控件都在System.Windows.Controls.Panel這個基類下面,使用 Panel 元素在WPF應用程序中放置和排列子對象。它具體包括哪些布局控件以及如何使用這些布局控件、如何開發自定義的布局控件,也就是本文所要討論的范疇:

  Panel具體繼承關系詳見下面類圖:

  如上圖,公共屬性太多了,就簡單介紹幾個常見的屬性:Margin是元素與其停放父元素的間距;Padding是指在本元素內部的元素內容與邊緣的距離;FlowDirection屬性標示元素的內容顯示方向;Panel.ZIndex是相對于顯示屏的Z軸坐標,用于調整層疊元素的顯示先后;RenderTransform和LayoutTransform用來將縮放和旋轉的變換應用到某個元素上。

  一個Panel 的呈現是測量和排列Children子元素、然后在屏幕上繪制它們的過程。所以在布局的過程中會經過一系列的計算,那么Children 越多,執行的計算次數就越多。如果不需要較為復雜的 Panel(如 Grid和自定義復雜的Panel),則可以使用構造相對簡單的布局(如 Canvas、UniformGrid等),這種布局可帶來更好的性能。如果有可能,我們應盡量避免不必要地調用 UpdateLayout方法。
  每當Panel內的子元素改變其位置時,布局系統就可能觸發一個新的處理過程。對此,了解哪些事件會調用布局系統就很重要,因為不必要的調用可能導致應用程序性能變差。
  換句話說,布局是一個遞歸系統,實現在屏幕上對元素進行大小調整、定位和繪制,然后進行呈現。具體如下圖,要實現控件0的布局,那么先要實現0的子控件01,02...的布局,要實現01的布局,那么得實現01的子控件001,002...的布局,如此循環直到子控件的布局完成后,再完成父控件的布局,最后遞歸回去直到遞歸結束,這樣整個布局過程就完成了。

  布局系統為 Children 集合的每個成員完成兩個處理過程:測量處理過程(Measure)和排列處理過程(Arrange)。每個子 Panel 均提供自己的 MeasureOverride 和 ArrangeOverride 方法,以實現自己特定的布局行為。

  四. Canvas

  Canvas比較簡單,只是一個存儲元素的容器,它不會自動調整內部元素的排列及大小。不指定元素位置,元素將默認顯示在畫布的左上方。Canvas的主要用途是用來畫圖。Canvas默認不會自動裁減超過自身范圍的內容,即溢出的內容會顯示在Canvas外面,這是因為默認 ClipToBounds="False";我們可以通過設置ClipToBounds="True來裁剪多出的內容。

Canvas1

  要實現的效果如下圖(用XAML和C#實現同一效果):

canvas

  XAML代碼實現:

<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   x:Class="WPFLayoutDemo.CanvasDEMO"
   x:Name="Window"
   Title="CanvasDEMO"
   WindowStartupLocation="CenterScreen" 
   Width="640" Height="480">
    <Canvas Margin="0,0,0,0" Background="White">
      <Rectangle Fill="Red" 
         Stroke="Azure" 
         Width="209" 
         Height="159" 
         Canvas.Left="310" Canvas.Top="181"/>
      <Ellipse Fill="Azure" 
         Stroke="Green" 
         Width="258" Height="97" 
         Panel.ZIndex="1" 
         Canvas.Left="165" Canvas.Top="145"/>
    </Canvas>
</Window>

  C#代碼實現:

namespace WPFLayoutDemo
{
   public partial class CanvasDEMOCodeBehind
   {
     public CanvasDEMOCodeBehind()
    {
       this.InitializeComponent();
       Canvas canv = new Canvas();
       //把canv添加為窗體的子控件
        this.Content = canv;
       canv.Margin = new Thickness(0, 0, 0, 0);
       canv.Background = new SolidColorBrush(Colors.White);
       
       //Rectangle
       Rectangle r = new Rectangle();
       r.Fill = new SolidColorBrush(Colors.Red);
       r.Stroke = new SolidColorBrush(Colors.Red);
       r.Width = 145;
       r.Height = 126;
       r.SetValue(Canvas.LeftProperty,(double)124);
       r.SetValue(Canvas.TopProperty,(double)122);
       canv.Children.Add(r);
       //Ellipse
       Ellipse el = new Ellipse();
       el.Fill = new SolidColorBrush(Colors.Azure);
       el.Stroke = new SolidColorBrush(Colors.Azure);
       el.Width = 121;
       el.Height = 100;
       el.SetValue(Canvas.ZIndexProperty, 1);
       el.SetValue(Canvas.LeftProperty,(double)195);
       el.SetValue(Canvas.TopProperty,(double)191);
       canv.Children.Add(el);
    }
  }
}

  五. StatickPanel

  StatickPanel就是將子元素按照堆棧的形式一一排列,通過設置面板的Orientation屬性設置了兩種排列方式:橫排(Horizontal默認的)和豎排(Vertical)。縱向的StatickPanel默認每個元素寬度與面板一樣寬,反之橫向亦然。如果包含的元素超過了面板空間,它只會截斷多出的內容。元素的Margin屬性用于使元素之間產生一定得間隔,當元素空間大于其內容的空間時,剩余空間將由HorizontalAlignment和VerticalAlignment屬性來決定如何分配。其他屬性,大家可以看看如下類圖:

StackPanel1

  要實現的效果如下圖(用XAML和C#實現同一效果): stackpanel

  XAML代碼實現:

<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   x:Class="WPFLayoutDemo.StackPanelDEMO"
   x:Name="Window"
   Title="StackPanelDEMO"
   WindowStartupLocation="CenterScreen" 
   Width="640" Height="480">
  <StackPanel Margin="0,0,0,0" Background="White" Orientation="Vertical">
    <Button Content="Top of Stack"/>
    <Button Content="Middle of Stack"/>
    <Button Content="Bottom Of Stack"/>
  </StackPanel>
</Window>

  C#代碼實現:

namespace WPFLayoutDemo
{
   public partial class StackPanelDEMOCodeBehind
   {
     public StackPanelDEMOCodeBehind()
    {
       this.InitializeComponent();
       StackPanel sp = new StackPanel();
       //把sp添加為窗體的子控件
       this.Content = sp;
       sp.Margin = new Thickness(0, 0, 0, 0);
       sp.Background = new SolidColorBrush(Colors.White);
       sp.Orientation = Orientation.Vertical;
       //Button1
       Button b1 = new Button();
       b1.Content = "Top of Stack";
       sp.Children.Add(b1);

//Button2
Button b2 = new Button();
b2.Content = "Middle of Stack";
sp.Children.Add(b2);

//Button3
Button b3 = new Button();
b3.Content = "Bottom of Stack";
sp.Children.Add(b3);
}
}
}

 

0
0
 
標簽:WPF 布局
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()