設計一個開關面版如下:
2

  

其中xxx panel的個數不一定, 所以要動態生成。 panel 皆以 checkbox 物件為主, 因此用陣列的方式來產生 checkbox 應用上較為便利。
checkbox 陣列結合 panel  好讓 panel checkbox 整體視為一個物件, 這樣只需要動態產生 panel 陣列, checkbox陣列便會同時被產生。

 

步驟一:

要動態產生開關, 非動態產生的部份就得先自行建立, 這部份不多說了

1  

 

步驟二:

設計如下的開關 panel

5  

===================================================

      public class panOnOff : Panel
      {

public int frmIndex;                              // 計錄陣列的指標
          
public string OComId;                             // 開關名稱
  
    public CheckBox[] ckbCs = new CheckBox[6];        // 開關名稱, 以及C1~C5等共六個開關

          public panOnOff(int tmpfrmIndex, string tmpOComId)
          {
               
 frmIndex = tmpfrmIndex;
                OComId = tmpOComId;

                this.Width = 230;
                this.Height = 30;
                this.Left = 8;
                this.Visible = true;
                this.Top = 47 + this.Height * frmIndex;      // 利用指標來設定物件的 Top
                this.BorderStyle = BorderStyle.FixedSingle;

 

                for (int i = 0; i < ckbCs.Length; i++)
                {
                    ckbCs[i] = new CheckBox();
                    ckbCs[i].Top = 3;
                    ckbCs[i].Left = 58 + 38 * (i - 1);       // 橫向排列六個 checkbox
                    this.Controls.Add(ckbCs[i]);
                    ckbCs[i].Visible = true;
                    ckbCs[i].BringToFront();                 // checkbox擺放到panel之上
                }
                ckbCs[0].Left = 3;                        // 其中第一個 checkbox要微調
                ckbCs[0].Text = OComId;                   // 並指定開關名稱
            }
        }
===================================================

 

步驟三: 實作panel開關面版

假設要產生的開關面版有 ComIDCount , 動態產生panel的程式碼如下:
===================================================

// 1. 必要的變數與變數要先行宣告好

int ComIDCount = 3;            // 假設要產生三組開關
          
string[] ComID = new string[ComIDCount];
    
panOnOff[] gbpanOnOff = new panOnOff[ComIDCount];

 

// 2. 設計一個動態產生開關面版的函數如下
           
private void SetOnOff( )
     {
          ComID[0] = "TXO";   //  自行為開關面版0取名
          ComID[1] = "TEO";   //  自行為開關面版1取名
          ComID[2] = "TFO";   //  自行為開關面版2取名 

for (int i = 0; i < ComIDCount; i++)
     {
         panOnOff[i] = new panOnOff(i,ComID[i]);
         this.Controls.Add(panOnOff[i]);
         this.Height = this.Height + modGlobal.gbpanOnOff[i].Height;  // 同步調整面版高度
           
}
     this.Height = this.Height + 15;  // 微調面版高度
}
===================================================

從以上程式碼可知, 一開始的panel物件若有架構好, 動態產生開關面版就變動容易多了...  : )

實作後的畫面如下:

2  

 

 

 

動態產生物件對大部份的人來說並不是件困難的事, 重要的是要如何結合 checkbox 的事件, 好讓程式可以清楚知道使用者正在點選哪一個checkbox, 如下所示:

3  

 

要產生以上的結果, 其邏輯如下:

一.  首先我們必須先為每個checkbox命名, 通常我們會用指標的方式來命名較方便應用;

二.  產生一個委派事件, 並讓checkboxcheckchanged的事件被觸發時, 經由委派事件傳遞該checkbox所對應的panel指標以及自身的指標名稱;

三.  在動態產生開關面版的函數將checkbox連結該委派事件, 以接收來自己checkchaged的事件;

 

以下紅色部份為原程式加入委派事件所須的程式碼:

// 先在宣告區宣告一個委派函數
public delegate void CheckChangeDelegate(int frmIndex, int ckbIndex);

panel物件部份:
===================================================

      public class panOnOff : Panel
      {

        // panel 物介裡產生一個委派事件
                
public event CheckChangeDelegate CheckChangeEvent;

public int frmIndex;                         // 計錄陣列的指標
     public string OComId;                        // 開關名稱
     public CheckBox[] ckbCs = new CheckBox[6];   // 開關名稱, 以及C1~C5等共六個開關

          public panOnOff(int tmpfrmIndex, string tmpOComId)
          {
               frmIndex = tmpfrmIndex;
               OComId = tmpOComId;

               this.Width = 230;
               this.Height = 30;
               this.Left = 8;
               this.Visible = true;
               this.Top = 47 + this.Height * frmIndex;  // 例用指標來設定物件的 Top
               this.BorderStyle = BorderStyle.FixedSingle;

               for (int i = 0;i < ckbCs.Length;i++)
               {
                    ckbCs[i] = new CheckBox();
                    ckbCs[i].Top = 3;
                    ckbCs[i].Left = 58 + 38 * (i - 1);   // 橫向排列六個 checkbox
                    this.Controls.Add(ckbCs[i]);

 ckbCs[i].Name = i.ToString();   // checkbox 命名, 名稱就以 i 定義之.
      ckbCs[i].Visible = true;
      ckbCs[i].BringToFront();                       // checkbox擺放到panel之上

     // 為每一個checkbox checkboxchanged的事件連結
         
ckbCs[i].CheckedChanged += new System.EventHandler(ckbCs_CheckedChanged);
 }

                ckbCs[0].Left = 3;                      // 其中第一個 checkbox要微調
                ckbCs[0].Text = OComId;                 // 並指定開關名稱
            }

           // checkchanged事件被觸發時, 就將自身的frmIndex以及物件命稱傳給委派事件
           private void ckbCs_CheckedChanged(object sender, EventArgs e)
           {
                CheckBox tmpckb = (CheckBox)sender;
                CheckChangeEvent(frmIndex, Convert.ToInt16(tmpckb.Name));
           }
        }

===================================================

 

動態產生開關面版的函數部份

===================================================

private void SetOnOff( )
    
{

     ComID[0] = "TXO";   //  自行為開關面版0取名
          ComID[1] = "TEO";   //  自行為開關面版1取名
          
     ComID[2] = "TFO";   //  自行為開關面版2取名

 

for (int i = 0; i < ComIDCount; i++)
     {
         panOnOff[i] = new panOnOff(i,ComID[i]);
         this.Controls.Add(panOnOff[i]);
         this.Height = this.Height + modGlobal.gbpanOnOff[i].Height;  // 同步調整面版高度 

            // 透過委派函數連結來自panel物件的委派事件
                       
panOnOff[i].CheckChangeEvent += new CheckChangeDelegate(OnOff_CheckChangeEvent);
        
}
          this.Height = this.Height + 15;  // 微調面版高度
           
}

// 接收來自委派事件所傳遞的參數值
       
private void frmOnOff_CheckChangeEvent(int frmIndex, int ckbIndex)
    {
        
Console.WriteLine("frmIndex:" + frmIndex + ", ckbIndex:" + ckbIndex);
   
}

 ===================================================

 

arrow
arrow
    全站熱搜

    Keep Practicing 發表在 痞客邦 留言(0) 人氣()