星期四, 7月 31, 2014

[C#] 動態產生內含 6 個 CheckBox 的 Panel

論壇問題,把這問題需求整理為
根據使用者輸入數字,動態產生內含 6 個 CheckBox 的 Panel,並需要利用 Text File 記錄使用者勾選選項
[C#] 動態產生內含 6 個 CheckBox 的 Panel
namespace DynamicAddCheckBoxs
{
    class CheckBoxInfo
    {
        public string plName { get; set; }
        public string cbName { get; set; }

        public CheckBoxInfo(string _plName , string _cbName)
        {
            this.plName = _plName;
            this.cbName = _cbName;
        }
    }
}

/*
 * 需求:根據使用者輸入的數字產生 Panel 內含 6 個 CheckBox,且必須記錄使用者勾選結果
 * Database:利用 Text File 來儲存使用者勾選結果,每筆記錄格式為 PanelName,CheckBoxName,Text File 內只記錄使用者勾選資料(CheckBox.Checked = .T.)
 */

// 引用該 namespace
using System.IO;

namespace DynamicAddCheckBoxs
{
    public partial class DynamicAddCheckBoxs : Form
    {
        public DynamicAddCheckBoxs()
        {
            InitializeComponent();
        }

        // 利用 Text 檔案來記錄使用者勾選結果
        string txtPath = "D:\\DataSource.txt";

        private void DynamicAddCheckBoxs_Load(object sender, EventArgs e)
        {
            // 預設值
            txtQty.Text = "2";
        }

        private void btnRun_Click(object sender, EventArgs e)
        {
            // 防呆 1:避免 Text 檔案不存在
            if (!File.Exists(txtPath))
            {
                string message = "偵測不到用來記錄使用者勾選資料的 Text,請確認該檔案存在或自行建立並修改 txtPath 參數";
                MessageBox.Show(message, "Text 檔案不存在", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 防呆 2:避免使用者輸入非數字或小於等於零數字
            int plcount = 0;
            if (!(int.TryParse(txtQty.Text, out plcount)) || plcount <= 0) return;

            dynamicControls(plcount);
            List<Checkboxinfo> cbinfos = txtRead(txtPath);
            checkBoxFill(cbinfos);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            txtWrite(txtPath);
        }

        private void dynamicControls(int _plcount)
        {
            // 先清除 Form 上的 Panel,避免使用者重覆操作,會造成 Panel 數目不正確,EX:先輸入 5,再輸入 2
            List<Panel> plremoves = this.Controls.OfType<Panel>().ToList();
            foreach (Panel plremove in plremoves)
            {
                this.Controls.Remove(plremove);
            }

            for (int i = 0; i < _plcount; i++)
            {
                Panel pl = new Panel();
                pl.Name = string.Format("pl{0}", i);
                pl.Left = 50;

                // Top 運算式數字說明
                // 50:Panel 和 Form 之間的預設距離
                // (50 * (i + 1)):每個 Panel 之間根據 i 逐漸往 Form Bottom 移動
                // (10 * i):Panel 和 Panel 之間的距離
                pl.Top = 50 + (50 * (i + 1)) + (10 * i);
                pl.Height = 50;
                pl.Width = this.Width - 100;
                pl.BorderStyle = BorderStyle.FixedSingle;
                pl.Visible = true;
                this.Controls.Add(pl);

                for (int j = 0; j < 6; j++)
                {
                    CheckBox cb = new CheckBox();
                    cb.Name = string.Format("cb{0}", j);
                    cb.Text = string.Format("{0}_cb{1}", pl.Name, j);
                    // Left 運算式數字說明
                    // 10:CheckBox 和 Panel Left 預設值
                    // (100 * j):每個 CheckBox 之間根據 j 逐漸往 Panel Right 移動
                    cb.Left = 10 + (100 * j);
                    cb.Top = 15;
                    cb.AutoSize = true;
                    pl.Controls.Add(cb);
                }
            }
        }

        private void checkBoxFill(List<Checkboxinfo> _cbinfos)
        {
            if (_cbinfos.Count == 0) return;

            foreach (CheckBoxInfo cbi in _cbinfos)
            {
                // 判斷控件是否存在
                Control[] plExist = this.Controls.Find(cbi.plName, false);
                if (plExist.Length == 0) continue;
                Control[] cbExist = this.Controls[cbi.plName].Controls.Find(cbi.cbName, false);
                if (cbExist.Length == 0) continue;

                // 判斷控件是否為 CheckBox
                object cbExam = this.Controls[cbi.plName].Controls[cbi.cbName];
                if (!(cbExam is CheckBox)) continue;
                CheckBox cbGet = cbExam as CheckBox;
                if (cbGet == null) continue;
                cbGet.Checked = true;
            }
        }

        #region Text 操作相關
        private List<Checkboxinfo> txtRead(string _txtPath)
        {
            List<Checkboxinfo> cbinfos = new List<Checkboxinfo>();
            using (StreamReader sr = new StreamReader(_txtPath))
            {
                string rowcontent = "";
                string plName = "";
                string cbName = "";
                while (!(string.IsNullOrEmpty((rowcontent = sr.ReadLine()))))
                {
                    string[] arr = rowcontent.Split(',');
                    plName = arr[0].ToString();
                    cbName = arr[1].ToString();
                    cbinfos.Add(new CheckBoxInfo(plName, cbName));
                }
            }
            return cbinfos;
        }

        private void txtWrite(string _txtPath)
        {
            StringBuilder sb = new StringBuilder();
            string rowcontent = "";

            foreach (Panel pl in this.Controls.OfType<Panel>())
            {
                foreach (CheckBox cb in pl.Controls.OfType<Checkbox>())
                {
                    // 只記錄 Checked = True 的資料
                    if (cb.Checked == false) continue;
                    // Text File 內每筆資料格式為 PanelName,CheckBoxName
                    rowcontent = string.Format("{0},{1}", pl.Name, cb.Name);
                    sb.AppendLine(rowcontent);
                }
            }

            using (StreamWriter sw = new StreamWriter(_txtPath, false))
            {
                sw.Write(sb);
            }
        } 
        #endregion
    }
}

沒有留言:

張貼留言