NO IMAGE

點選開啟連結

3 佈局中的空白區域

在.net Framework中,每個控制元件和其所處的容器以及容器內控制元件之間,都存在一個可以調整的空白區域,這個空白區域純粹是為了佈局的美觀性而存在的。

容器和容器內控制元件之間的空白稱為容器的Padding屬性,容器內控制元件之間的空白稱為控制元件的Margin屬性。看一下示意圖:

Padding和Margin示意圖 
圖1 Padding和Margin示意圖

很容易理解,藍色箭頭表示的四個空白位置為窗體容器的Padding屬性;黃色箭頭表示的四個空白位置為按鈕控制元件的Margin屬性。

注意:一個控制元件離其所在容器四周的距離,是容器的Padding屬性和該控制元件的Margin屬性之和。例如圖中的按鈕0,它和Form容器的左邊的距離就是Form容器的Padding屬性和按鈕0的Margin屬性之和。

Padding屬性和Margin屬性的值都是一個Padding類的物件,Padding類為值型別物件,具有四個整型型別屬性:Left,Top,Right,Bottom,分別表左上右下四個方向的空白大小。Padding類還有一個特殊的整型型別屬性:All,當Left,Top,Right,Bottom屬性值相同時,All屬性是Left,Top,Right,Bottom其中一個的值,否則All屬性值為-1。即當Padding物件的All屬性為-1時,表示其Left,Top,Right,Bottom屬性值不同,當All屬性值為正整數時,表示Left,Top,Right,Bottom值相同,等於All的值。

可以猜想,Padding類大致如下:

Padding.cs

[c-sharp] view
plain
 copy

  1. public struct Padding {  
  2.    
  3.     // 欄位  
  4.     private bool all;  
  5.     private int top;  
  6.     private int left;  
  7.     private int right;  
  8.     private int bottom;  
  9.    
  10.     // 靜態只讀欄位, 表示一個四周為0的Padding物件  
  11.     public static readonly Padding Empty = new Padding(0);  
  12.    
  13.     /// <summary>  
  14.     /// 構造器, 通過設定All屬性, 設定上下左右四個屬性值  
  15.     /// </summary>  
  16.     public Padding(int all) {  
  17.         // 設定all標誌為true  
  18.         this.all = true;  
  19.         // 設定上下左右四個欄位, 值相同  
  20.         this.top = this.left = this.right = this.bottom = all;  
  21.     }  
  22.    
  23.     /// <summary>  
  24.     /// 設定上下左右四個屬性值  
  25.     /// </summary>  
  26.     public Padding(int left, int top, int right, int bottom) {  
  27.         // 設定上下左右四個屬性值  
  28.         this.top = top;  
  29.         this.left = left;  
  30.         this.right = right;  
  31.         this.bottom = bottom;  
  32.    
  33.         // 根據上下左右四個屬性值是否相同設定all標誌  
  34.         this.all = (this.top == this.left) &&  
  35.             (this.left == this.right) &&  
  36.             (this.right == this.bottom) &&  
  37.             (this.bottom == this.top);  
  38.     }  
  39.    
  40.     /// <summary>  
  41.     /// All屬性, 如果上下左右屬性值相同, 則返回其中一個值, 否則返回-1  
  42.     /// </summary>  
  43.     public int All {  
  44.         get {  
  45.             // 根據all標誌是否為true, 決定返回上下左右任意值或-1  
  46.             return this.all ? this.top : -1;  
  47.         }  
  48.         set {  
  49.             // 設定all標誌為true  
  50.             this.all = true;  
  51.             // 設定上下左右四個欄位, 值相同  
  52.    
  53.         this.top = this.left = this.right = this.bottom = value;  
  54.         }  
  55.     }  
  56.    
  57.     /// <summary>  
  58.     /// 設定或獲取底部空白  
  59.     /// </summary>  
  60.     public int Bottom {  
  61.         get {  
  62.             return this.bottom;  
  63.         }  
  64.         set {  
  65.             this.bottom = value;  
  66.             // 根據上下左右四個屬性值是否相同設定all標誌  
  67.             this.all = (this.top == this.left) &&  
  68.                 (this.left == this.right) &&  
  69.                 (this.right == this.bottom) &&  
  70.                 (this.bottom == this.top);  
  71.         }  
  72.     }  
  73.    
  74.     /// <summary>  
  75.     /// 設定或獲取左邊空白  
  76.     /// </summary>  
  77.     public int Left {  
  78.         get {  
  79.             return this.left;  
  80.         }  
  81.         set {  
  82.             this.left = value;  
  83.             this.all = (this.top == this.left) &&  
  84.                 (this.left == this.right) &&  
  85.                 (this.right == this.bottom) &&  
  86.                 (this.bottom == this.top);  
  87.         }  
  88.     }  
  89.    
  90.     /// <summary>  
  91.     /// 設定或獲取右邊空白  
  92.     /// </summary>  
  93.     public int Right {  
  94.         get {  
  95.             return this.right;  
  96.         }  
  97.         set {  
  98.             this.right = value;  
  99.             this.all = (this.top == this.left) &&  
  100.                 (this.left == this.right) &&  
  101.                  (this.right == this.bottom) &&  
  102.                  (this.bottom == this.top);  
  103.         }  
  104.     }  
  105.    
  106.     /// <summary>  
  107.    
  108. /// 設定或獲取頂部空白  
  109.     /// </summary>  
  110.     public int Top {  
  111.         get {  
  112.             return this.top;  
  113.         }  
  114.         set {  
  115.             this.top = value;  
  116.             this.all = (this.top == this.left) &&  
  117.                 (this.left == this.right) &&  
  118.                 (this.right == this.bottom) &&  
  119.                 (this.bottom == this.top);  
  120.         }  
  121.     }  
  122.    
  123.     /// <summary>  
  124.     /// 獲取水平空白總和  
  125.     /// </summary>  
  126.     public int Horizontal {  
  127.         get {  
  128.             return this.right + this.left;  
  129.         }  
  130.     }  
  131.    
  132.     /// <summary>  
  133.     /// 獲取垂直空白總和  
  134.     /// </summary>  
  135.     public int Vertical {  
  136.         get {  
  137.             return this.top + this.bottom;  
  138.         }  
  139.     }  
  140.    
  141.     /// <summary>  
  142.     /// 獲取以空白值為屬性的Size型別物件  
  143.     /// </summary>  
  144.     public Size Size {  
  145.         get {  
  146.             return new Size(this.Horizontal, this.Vertical);  
  147.         }  
  148.     }  
  149.    
  150.     /// <summary>  
  151.     /// 靜態方法, 獲取兩個Padding物件的和  
  152.     /// (即將兩個物件的上下左右屬性各自相加後得到的Padding物件)  
  153.     /// </summary>  
  154.     public static Padding Add(Padding p1, Padding p2) {  
  155.         // 呼叫過載的+運算子  
  156.         return (p1 + p2);  
  157.     }  
  158.    
  159.     /// <summary>  
  160.     /// 靜態方法, 獲取兩個Padding物件的差  
  161.     /// (即將兩個物件的上下左右屬性各自想減後得到的Padding物件)  
  162.     /// </summary>  
  163.     public static Padding Subtract(Padding p1, Padding p2) {  
  164.    
  165.     // 呼叫過載的-運算子  
  166.         return (p1 – p2);  
  167.     }  
  168.    
  169.     /// <summary>  
  170.     /// 覆蓋物件的比較方法  
  171.     /// </summary>  
  172.     public override bool Equals(object other) {  
  173.         // 判斷物件的型別後呼叫物件過載的==運算子  
  174.         return ((other is Padding) && (((Padding)other) == this));  
  175.     }  
  176.    
  177.     /// <summary>  
  178.     /// 過載+運算子, 表示兩個Padding型別物件相加  
  179.     /// </summary>  
  180.     public static Padding operator +(Padding p1, Padding p2) {  
  181.         // 將兩個物件的上下左右屬性各自相加後得到的新的Padding物件  
  182.         return new Padding(p1.Left + p2.Left,  
  183.             p1.Top + p2.Top,  
  184.             p1.Right + p2.Right,  
  185.             p1.Bottom + p2.Bottom);  
  186.     }  
  187.    
  188.     /// <summary>  
  189.     /// 過載-運算子, 表示兩個Padding型別物件相減  
  190.     /// </summary>  
  191.     public static Padding operator -(Padding p1, Padding p2) {  
  192.         // 將兩個物件的上下左右屬性各自相減後得到的新的Padding物件  
  193.         return new Padding(p1.Left – p2.Left,  
  194.             p1.Top – p2.Top,  
  195.             p1.Right – p2.Right,  
  196.             p1.Bottom – p2.Bottom);  
  197.     }  
  198.    
  199.     /// <summary>  
  200.     /// 過載==運算子  
  201.     /// </summary>  
  202.     public static bool operator ==(Padding p1, Padding p2) {  
  203.         if (p1.all && p2.all) { // 如果p1和p2的all欄位都為true, 則比較它們的Top屬性  
  204.             return p1.Top == p2.Top;  
  205.         } else { // 否則將它們對應屬性一一比較  
  206.             return (p1.Left == p2.Left) &&  
  207.                 (p1.Top == p2.Top) &&  
  208.    
  209.             (p1.Right == p2.Right) &&  
  210.                 (p1.Bottom == p2.Bottom);  
  211.         }  
  212.     }  
  213.    
  214.     /// <summary>  
  215.     /// 過載!=運算子  
  216.     /// </summary>  
  217.     public static bool operator !=(Padding p1, Padding p2) {  
  218.         return !(p1 == p2);  
  219.     }  
  220.    
  221.     /// <summary>  
  222.     /// 覆蓋GetHashCode方法(因為覆蓋了Equals方法)  
  223.     /// </summary>  
  224.     public override int GetHashCode() {  
  225.         return this.left ^ this.Right ^ this.Top ^ this.Bottom;  
  226.     }  
  227.    
  228.     /// <summary>  
  229.     /// 覆蓋ToString方法, 返回字串表示  
  230.     /// </summary>  
  231.     public override string ToString() {  
  232.         return string.Format("{ Left={0}, Top={1}, Right={2}, Bottom={3} }",  
  233.             this.Left, this.Top, this.Right, this.Bottom);  
  234.     }  
  235. }  

通過Padding類的原始碼(猜想,非官方原始碼),可以瞭解Padding五個屬性的工作方式,順便複習一下值型別構造、比較、Empty欄位以及運算子過載的知識。

4 流式佈局

我們已經瞭解,控制元件都具備Dock方位佈局能力,可以按照“上下左右中”五個方位將自身錨定在容器上進行佈局。但我們也看到,如果要讓容器內的控制元件進行其它形式的佈局(例如上一節中控制元件成行列布局),則一般需要在容器的Resize事件處理方法內,為容器內的所有控制元件使用演算法進行佈局。其複雜度和程式碼量都不好控制。

除非有特殊需要,一般情況下我們儘量不要自己書寫大段的控制元件佈局程式碼,這些程式碼很不經濟。.net Framework提供了若干個專門用來負責佈局控制元件的容器,使用起來非常方便。

FlowLayoutPanel稱為流式佈局面板容器,它的作用是將容器內控制元件按照從左到右(或從右到左)以及從上到下(或從下到上)的順序排列布局。幾點重要屬性:

  • FlowDirection屬性:FlowDirection列舉型別。表示容器內控制元件佈局方向。分別為:LeftToRight(從左到右),TopDown(從上到下),RightToLeft(從右到左),BottomUp(從下到上)四個列舉項。
  • WrapContents屬性:bool型別。表示是否為容器內控制元件佈局自動換行。對於屬性值為true,當控制元件超出容器範圍,則將控制元件自動排列到下一行;對於false,則忽略超出部分的顯示。
  • AutoScroll屬性:bool型別。表示當WrapContents屬性為false時,當控制元件超出容器範圍時,容器是否顯示一個滾動條。

好了,該容器使用起來很簡單,我們通過例項來說明:

介面顯示效果圖如下:

程式介面顯示效果圖圖2
程式介面顯示效果圖

程式碼如下:

Program.cs

[c-sharp] view
plain
 copy

  1. using System;  
  2. using System.Drawing;  
  3. using System.Windows.Forms;  
  4.    
  5. namespace Edu.Study.Graphics.FlowLayout {  
  6.     /// <summary>  
  7.     /// 窗體類  
  8.     /// </summary>  
  9.     class MyForm : Form {  
  10.    
  11.         /************ 流式佈局面板 ************/  
  12.         // 頂部流式佈局面板  
  13.         private FlowLayoutPanel topPane;  
  14.         // 底部流式佈局面板  
  15.         private FlowLayoutPanel bottomPane;  
  16.    
  17.         /************ 文字標籤 ************/  
  18.         // 佈局方向標籤  
  19.         private Label flowDirectionComboBoxLabel;  
  20.         // 容器Padding尺寸標籤  
  21.         private Label panddingTrackBarLabel;  
  22.         // 控制元件Margin尺寸標籤  
  23.         private Label marginTrackBarLabel;  
  24.    
  25.         /************ 組合下拉選單框 ************/  
  26.         // 選擇流式佈局方向的下拉選單框  
  27.         private ComboBox flowDirectionComboBox;  
  28.    
  29.         /************ 核取方塊 ************/  
  30.         // 佈局容器是否自動換行復選框  
  31.         private CheckBox wrapCheckBox;  
  32.         // 容器是否自動換行復選框  
  33.         private CheckBox autoScrollCheckBox;  
  34.    
  35.         /************ 數字調節塊 ************/  
  36.         // 設定容器Padding屬性的調節塊  
  37.         private TrackBar panddingTrackBar;  
  38.         // 設定容器內控制元件Margin屬性的調節塊  
  39.         private TrackBar marginTrackBar;  
  40.    
  41.         /************ 文字框 ************/  
  42.         // 顯示容器Padding屬性值的調節塊  
  43.         private TextBox pandingTrackBarValueTextBox;  
  44.         // 顯示容器內控制元件Margin屬性值的調節塊  
  45.         private TextBox marginTrackBarValueTextBox;  
  46.    
  47.         /************ 按鈕 ************/  
  48.         // bottomPane內放置的按鈕控制元件, 是一個Button類陣列  
  49.         private Button[] buttons;  
  50.    
  51.         /// <summary>  
  52.         /// 構造器, 初始化所有控制元件  
  53.         /// </summary>  
  54.         public MyForm() {  
  55.    
  56.             /************ topPane控制元件初始化 ************/  
  57.             this.topPane = new FlowLayoutPanel();  
  58.             // 設定topPane容器停靠在窗體頂部  
  59.             this.topPane.Dock = DockStyle.Top;  
  60.             // 設定topPane容器佈局方向: 從左到右  
  61.             this.topPane.FlowDirection = FlowDirection.LeftToRight;  
  62.             // 設定topPane容器的Padding屬性  
  63.             this.topPane.Padding = new Padding(30);  
  64.             // 設定topPane容器的邊框屬性, 呈現3D效果  
  65.             this.topPane.BorderStyle = BorderStyle.Fixed3D;  
  66.             // 設定topPane容器不自動換行  
  67.             this.topPane.WrapContents = false;  
  68.             // 設定topPane容器具有自動滾動條  
  69.             this.topPane.AutoScroll = true;  
  70.    
  71.             /************ flowDirectionComboBoxLabel控制元件初始化 ************/  
  72.             this.flowDirectionComboBoxLabel = new Label();  
  73.             // 設定flowDirectionComboBoxLabel控制元件Margin屬性  
  74.             this.flowDirectionComboBoxLabel.Margin = new Padding(2, 6, 0, 3);  
  75.             // 設定flowDirectionComboBoxLabel控制元件呈現文字  
  76.             this.flowDirectionComboBoxLabel.Text = "佈局方向:";  
  77.             // 設定flowDirectionComboBoxLabel控制元件自動調整尺寸  
  78.             this.flowDirectionComboBoxLabel.AutoSize = true;  
  79.             // 將flowDirectionComboBoxLabel控制元件增加在topPane容器內  
  80.             this.topPane.Controls.Add(this.flowDirectionComboBoxLabel);  
  81.    
  82.             /************ flowDirectionComboBox控制元件初始化 ************/  
  83.             this.flowDirectionComboBox = new ComboBox();  
  84.             // 設定flowDirectionComboBox控制元件Margin屬性  
  85.             this.flowDirectionComboBox.Margin = new Padding(0, 3, 0, 3);  
  86.             // 設定flowDirectionComboBox控制元件下拉選單內容  
  87.             this.flowDirectionComboBox.Items.AddRange(new object[] {  
  88.                 FlowDirection.LeftToRight,  
  89.                 FlowDirection.RightToLeft,  
  90.                 FlowDirection.TopDown,  
  91.                 FlowDirection.BottomUp  
  92.             });  
  93.             // 設定flowDirectionComboBox控制元件下拉預設選中項  
  94.             this.flowDirectionComboBox.SelectedIndex = 0;  
  95.             // 設定flowDirectionComboBox控制元件選擇項改變後通知事件  
  96.             this.flowDirectionComboBox.SelectedIndexChanged +=  
  97.                 new EventHandler(FlowDirectionComboBoxSelectedValueChanged);  
  98.             // 將flowDirectionComboBox控制元件增加在topPane容器內  
  99.             this.topPane.Controls.Add(this.flowDirectionComboBox);  
  100.    
  101.             /************ wrapCheckBox控制元件初始化 ************/  
  102.             this.wrapCheckBox = new CheckBox();  
  103.             // 設定wrapCheckBox控制元件Margin屬性  
  104.             this.wrapCheckBox.Margin = new Padding(20, 5, 0, 5);  
  105.             // 設定wrapCheckBox控制元件自動調整尺寸  
  106.             this.wrapCheckBox.AutoSize = true;  
  107.             // 設定wrapCheckBox控制元件呈現文字  
  108.             this.wrapCheckBox.Text = "是否自動換行";  
  109.             // 設定wrapCheckBox控制元件選中狀態改變通知事件  
  110.             this.wrapCheckBox.CheckedChanged += new EventHandler(WarpCheckBoxCheckedChanged);  
  111.             // 將wrapCheckBox控制元件增加在topPane容器內  
  112.             this.topPane.Controls.Add(this.wrapCheckBox);  
  113.    
  114.             /************ autoScrollCheckBox控制元件初始化 ************/  
  115.             this.autoScrollCheckBox = new CheckBox();  
  116.             // 設定autoScrollCheckBox控制元件Margin屬性  
  117.             this.autoScrollCheckBox.Margin = new Padding(20, 5, 0, 5);  
  118.             // 設定autoScrollCheckBox控制元件自動調整尺寸  
  119.             this.autoScrollCheckBox.AutoSize = true;  
  120.             // 設定autoScrollCheckBox控制元件呈現文字  
  121.             this.autoScrollCheckBox.Text = "是否使用滾動條";  
  122.             // 設定autoScrollCheckBox控制元件選中狀態改變通知事件  
  123.             this.autoScrollCheckBox.CheckedChanged += new EventHandler(AutoScrollCheckBoxChanged);  
  124.             // 將autoScrollCheckBox控制元件增加在topPane容器內  
  125.             this.topPane.Controls.Add(this.autoScrollCheckBox);  
  126.    
  127.             /************ panddingTrackBarLabel控制元件初始化 ************/  
  128.             this.panddingTrackBarLabel = new Label();  
  129.             // 設定panddingTrackBarLabel控制元件自動調整尺寸  
  130.             this.panddingTrackBarLabel.AutoSize = true;  
  131.             // 設定panddingTrackBarLabel控制元件Margin屬性  
  132.             this.panddingTrackBarLabel.Margin = new Padding(20, 5, 0, 5);  
  133.             // 設定panddingTrackBarLabel控制元件呈現文字  
  134.             this.panddingTrackBarLabel.Text = "更改容器的 Padding:";  
  135.             // 將panddingTrackBarLabel控制元件增加在topPane容器內  
  136.             this.topPane.Controls.Add(this.panddingTrackBarLabel);  
  137.    
  138.             /************ panddingTrackBar控制元件初始化 ************/  
  139.             this.panddingTrackBar = new TrackBar();  
  140.             // 設定panddingTrackBar控制元件Margin屬性  
  141.             this.panddingTrackBar.Margin = new Padding(0, 3, 3, 3);  
  142.             // 設定panddingTrackBar控制元件寬度屬性  
  143.             this.panddingTrackBar.Width = 120;  
  144.             // 設定panddingTrackBar控制元件數值最小值  
  145.             this.panddingTrackBar.Minimum = 0;  
  146.             // 設定panddingTrackBar控制元件數值最大值  
  147.             this.panddingTrackBar.Maximum = 100;  
  148.             // 設定panddingTrackBar控制元件單位數值  
  149.             this.panddingTrackBar.TickFrequency = 1;  
  150.             // 設定panddingTrackBar控制元件數值改變時通知事件  
  151.             this.panddingTrackBar.ValueChanged += new EventHandler(PandingTrackBarValueChanged);  
  152.             // 將panddingTrackBar控制元件增加在topPane容器內  
  153.             this.topPane.Controls.Add(this.panddingTrackBar);  
  154.    
  155.             /************ pandingTrackBarValueTextBox控制元件初始化 ************/  
  156.             this.pandingTrackBarValueTextBox = new TextBox();  
  157.             // 設定pandingTrackBarValueTextBox控制元件Margin屬性  
  158.             this.pandingTrackBarValueTextBox.Margin = new Padding(0, 3, 3, 3);  
  159.             // 設定pandingTrackBarValueTextBox控制元件只讀  
  160.             this.pandingTrackBarValueTextBox.ReadOnly = true;  
  161.             // 設定pandingTrackBarValueTextBox控制元件寬度屬性  
  162.             this.pandingTrackBarValueTextBox.Width = 80;  
  163.             // 設定pandingTrackBarValueTextBox控制元件背景色屬性  
  164.             this.pandingTrackBarValueTextBox.BackColor = SystemColors.Window;  
  165.             // 將pandingTrackBarValueTextBox控制元件增加在topPane容器內  
  166.             this.topPane.Controls.Add(this.pandingTrackBarValueTextBox);  
  167.    
  168.             /************ marginTrackBarLabel控制元件初始化 ************/  
  169.             this.marginTrackBarLabel = new Label();  
  170.             // 設定marginTrackBarLabel控制元件自動調整尺寸  
  171.             this.marginTrackBarLabel.AutoSize = true;  
  172.             // 設定marginTrackBarLabel控制元件Margin屬性  
  173.             this.marginTrackBarLabel.Margin = new Padding(20, 5, 0, 5);  
  174.             // 設定marginTrackBarLabel控制元件呈現文字  
  175.             this.marginTrackBarLabel.Text = "更改容器內控制元件的 Margin:";  
  176.             // 將marginTrackBarLabel控制元件增加在topPane容器內  
  177.             this.topPane.Controls.Add(this.marginTrackBarLabel);  
  178.    
  179.             /************ marginTrackBar控制元件初始化 ************/  
  180.             this.marginTrackBar = new TrackBar();  
  181.             // 設定marginTrackBar控制元件Margin屬性  
  182.             this.marginTrackBar.Margin = new Padding(0, 3, 3, 3);  
  183.             // 設定marginTrackBar控制元件寬度屬性  
  184.             this.marginTrackBar.Width = 120;  
  185.             // 設定marginTrackBar控制元件數值最小值  
  186.             this.marginTrackBar.Minimum = 0;  
  187.             // 設定marginTrackBar控制元件數值最大值  
  188.             this.marginTrackBar.Maximum = 100;  
  189.             // 設定marginTrackBar控制元件單位數值  
  190.             this.marginTrackBar.TickFrequency = 1;  
  191.             // 設定marginTrackBar控制元件數值改變時通知事件  
  192.             this.marginTrackBar.ValueChanged += new EventHandler(MarginTrackBarValueChanged);  
  193.             // 將marginTrackBar控制元件增加在topPane容器內  
  194.             this.topPane.Controls.Add(this.marginTrackBar);  
  195.    
  196.             /************ marginTrackBarValueTextBox控制元件初始化 ************/  
  197.             this.marginTrackBarValueTextBox = new TextBox();  
  198.             // 設定marginTrackBarValueTextBox控制元件Margin屬性  
  199.             this.marginTrackBarValueTextBox.Margin = new Padding(0, 3, 3, 3);  
  200.             // 設定marginTrackBarValueTextBox控制元件只讀  
  201.             this.marginTrackBarValueTextBox.ReadOnly = true;  
  202.             // 設定marginTrackBarValueTextBox控制元件寬度屬性  
  203.             this.marginTrackBarValueTextBox.Width = 80;  
  204.             // 設定marginTrackBarValueTextBox控制元件背景色屬性  
  205.             this.marginTrackBarValueTextBox.BackColor = SystemColors.Window;  
  206.             // 將marginTrackBarValueTextBox控制元件增加在topPane容器內  
  207.             this.topPane.Controls.Add(this.marginTrackBarValueTextBox);  
  208.    
  209.             // 將topPane容器增加到窗體上  
  210.             this.Controls.Add(this.topPane);  
  211.    
  212.             /************ bottomPane容器初始化 ************/  
  213.             this.bottomPane = new FlowLayoutPanel();  
  214.             // 設定bottomPane容器停靠在窗體底部  
  215.             this.bottomPane.Dock = DockStyle.Bottom;  
  216.             // 設定bottomPane容器佈局方向: 從左到右  
  217.             this.bottomPane.FlowDirection = FlowDirection.LeftToRight;  
  218.             // 設定bottomPane容器的Padding屬性  
  219.             this.bottomPane.Padding = new Padding(30);  
  220.             // 設定bottomPane容器的邊框屬性, 呈現3D效果  
  221.             this.bottomPane.BorderStyle = BorderStyle.Fixed3D;  
  222.    
  223.             /************ wrapCheckBox控制元件初始化 ************/  
  224.             // 初始化200個Button物件的陣列  
  225.             this.buttons = new Button[200];  
  226.             // 初始化陣列中的每一項  
  227.             for (int i = 0; i < this.buttons.Length; i++) {  
  228.                 Button btn = new Button();  
  229.                 // 設定按鈕呈現文字  
  230.                 btn.Text = i.ToString();  
  231.                 // 設定按鈕的尺寸  
  232.                 btn.Size = new Size(100, 80);  
  233.                 buttons[i] = btn;  
  234.             }  
  235.             // 將所有的按鈕增加到bottomPane容器上  
  236.             this.bottomPane.Controls.AddRange(buttons);  
  237.    
  238.             // 將bottomPane容器增加到窗體上  
  239.             this.Controls.Add(this.bottomPane);  
  240.    
  241.             // 設定窗體最大化  
  242.             this.WindowState = FormWindowState.Maximized;  
  243.             // 設定窗體最小尺寸  
  244.             this.MinimumSize = new Size(800, 600);  
  245.         }  
  246.    
  247.         /// <summary>  
  248.         /// 覆蓋窗體OnLoad方法, 處理窗體第一次載入通知訊息  
  249.         /// </summary>  
  250.         protected override void OnLoad(EventArgs e) {  
  251.             base.OnLoad(e);  
  252.    
  253.             // 設定wrapCheckBox核取方塊Checked屬性和bottomPane容器WrapContents屬性值一致  
  254.             this.wrapCheckBox.Checked = this.bottomPane.WrapContents;  
  255.             // 設定autoScrollCheckBox核取方塊Checked屬性和bottomPane容器AutoScroll屬性值一致  
  256.             this.autoScrollCheckBox.Checked = this.bottomPane.AutoScroll;  
  257.             // 設定pandingTrackBarValueTextBox文字框文字為bottomPane容器Padding屬性值  
  258.             this.pandingTrackBarValueTextBox.Text = this.bottomPane.Padding.All.ToString();  
  259.             // 設定marginTrackBarValueTextBox文字框文字為按鈕控制元件Margin屬性值  
  260.             this.marginTrackBarValueTextBox.Text = this.buttons[0].Margin.All.ToString();  
  261.    
  262.             // 設定panddingTrackBar控制元件當前數值為bottomPane容器Padding屬性值  
  263.             this.panddingTrackBar.Value = this.bottomPane.Padding.All;  
  264.             // 設定marginTrackBar控制元件當前數值為按鈕控制元件Margin屬性值  
  265.             this.marginTrackBar.Value = this.buttons[0].Margin.All;  
  266.         }  
  267.    
  268.         /// <summary>  
  269.         /// 處理flowDirectionComboBox下拉選單控制元件選項改變事件  
  270.         /// </summary>  
  271.         private void FlowDirectionComboBoxSelectedValueChanged(object sender, EventArgs e) {  
  272.             // 設定bottomPane容器佈局方向與flowDirectionComboBox下拉選單選項一致  
  273.             this.bottomPane.FlowDirection = (FlowDirection)this.flowDirectionComboBox.SelectedItem;  
  274.         }  
  275.    
  276.         /// <summary>  
  277.         /// 處理wrapCheckBox核取方塊選擇狀態改變事件  
  278.         /// </summary>  
  279.         private void WarpCheckBoxCheckedChanged(object sender, EventArgs e) {  
  280.             // 設定bottomPane容器是否自動換行屬性與wrapCheckBox核取方塊選中狀態一致  
  281.             this.bottomPane.WrapContents = this.wrapCheckBox.Checked;  
  282.         }  
  283.    
  284.         /// <summary>  
  285.         /// 處理autoScrollCheckBox核取方塊選擇狀態改變事件  
  286.         /// </summary>  
  287.         private void AutoScrollCheckBoxChanged(object sender, EventArgs e) {  
  288.             // 設定bottomPane容器是否具備滾動條屬性與autoScrollCheckBox核取方塊選中狀態一致  
  289.             this.bottomPane.AutoScroll = this.autoScrollCheckBox.Checked;  
  290.         }  
  291.    
  292.         /// <summary>  
  293.         /// 處理panddingTrackBar控制元件數值改變事件  
  294.         /// </summary>  
  295.         private void PandingTrackBarValueChanged(object sender, EventArgs e) {  
  296.             // 設定bottomPane容器Padding屬性與panddingTrackBar當前數值一致  
  297.             this.bottomPane.Padding = new Padding(this.panddingTrackBar.Value);  
  298.             // 設定pandingTrackBarValueTextBox文字框文字內容為bottomPane容器Padding屬性值  
  299.             this.pandingTrackBarValueTextBox.Text = this.bottomPane.Padding.All.ToString();  
  300.         }  
  301.    
  302.         /// <summary>  
  303.         /// 處理marginTrackBarValueTextBox控制元件數值改變事件  
  304.         /// </summary>  
  305.         private void MarginTrackBarValueChanged(object sender, EventArgs e) {  
  306.             // 設定所有按鈕控制元件的Margin屬性與marginTrackBar當前數值一致  
  307.             foreach (Button btn in this.buttons) {  
  308.                 btn.Margin = new Padding(this.marginTrackBar.Value);  
  309.             }  
  310.             // 設定marginTrackBarValueTextBox文字框文字內容為按鈕Margin屬性值  
  311.             this.marginTrackBarValueTextBox.Text = this.buttons[0].Margin.All.ToString();  
  312.         }  
  313.    
  314.         /// <summary>  
  315.         /// 覆蓋父類OnResize方法, 處理窗體尺寸變化訊息通知  
  316.         /// </summary>  
  317.         protected override void OnResize(EventArgs e) {  
  318.             base.OnResize(e);  
  319.    
  320.             // 設定topPane容器高度為窗體客戶區高度1/6  
  321.             this.topPane.Height = this.ClientSize.Height / 6;  
  322.             // 設定bottomPane容器高度為窗體客戶區高度5/6  
  323.             this.bottomPane.Height = this.ClientSize.Height – this.ClientSize.Height / 6;  
  324.         }  
  325.     }  
  326.    
  327.    
  328.     /// <summary>  
  329.     /// 包含住方法的類  
  330.     /// </summary>  
  331.     static class Program {  
  332.         /// <summary>  
  333.         /// 應用程式的主入口點。  
  334.         /// </summary>  
  335.         static void Main() {  
  336.             Application.EnableVisualStyles();  
  337.             Application.SetCompatibleTextRenderingDefault(false);  
  338.             Application.Run(new MyForm());  
  339.         }  
  340.     }  
  341. }  

本節程式碼下載

本次程式碼中,我們用到了一些其它控制元件,包括:

  • 文字標籤控制元件(Label類);
  • 文字框控制元件(TextBox類);
  • 組合下拉選單框控制元件(ComboBox類);
  • 數值調節滑塊控制元件(TrackBar類)

程式碼中除了展示FlowLayoutPanel容器和上述控制元件的用法外(特別注意這些控制元件的事件處理),還展示了容器的Padding屬性和控制元件(以Button為例)的Margin屬性,仔細閱讀程式碼,靈活的掌握上述內容。