天天看點

C#Winform自定義DataGridView 附源碼-最終版

C#​

​Winform​

​​自定義​

​DataGridView​

​ 附源碼-最終版

public partial class PersonalAccountForm : Form
    {
        private DataGridView dataGridView = new DataGridView();
        private VScrollBar scrollBar = new VScrollBar();        
        public static double result;//用于訓示計算結果-數字
        public static double[] resultArray = null;//存放計算結果的數組

        public PersonalAccountForm()
        {
            InitializeComponent();

            //設定scrollBar屬性
            scrollBar.Width = 5;
            scrollBar.Maximum = dataGridView.RowCount;//設scrollBar最大值為dataGridView的行數
            scrollBar.SmallChange = 1;
            scrollBar.LargeChange = 1;
            scrollBar.Dock = DockStyle.Right;//設定scrollBar在父控件的右側    
            scrollBar.Hide();

            //scrollBar事件
            scrollBar.MouseEnter += scrollBar_MouseEnter;
            scrollBar.MouseLeave += scrollBar_MouseLeave;
            scrollBar.Scroll += scrollBar_Scroll;

            //将scrollBar添加到dataGridView中
            dataGridView.Controls.Add(scrollBar);

            //設定dataGridView屬性
            dataGridView.Dock = DockStyle.Fill;
            dataGridView.ScrollBars = ScrollBars.None;            
            dataGridView.SelectionMode = DataGridViewSelectionMode.CellSelect;//一次選擇一個單元格
            dataGridView.MultiSelect = false;
            dataGridView.BackgroundColor =SystemColors.Control;
            dataGridView.BorderStyle = BorderStyle.None;
            dataGridView.GridColor = Color.LightGray;
            dataGridView.RowHeadersVisible = false;//這樣左側空白列就沒有了
            dataGridView.AllowUserToResizeColumns = false;
            dataGridView.AllowUserToResizeRows = false;
            dataGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;//這樣就禁止拖動标題行
            dataGridView.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;//這樣标題行内容在垂直水準方向均居中
            dataGridView.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;//這樣所有單元格内容在垂直水準方向均居中
            dataGridView.ColumnHeadersHeight = 30;//設定列标題行高為30
            dataGridView.RowTemplate.Height = 23;//設定單元格行高為23
            dataGridView.ColumnHeadersDefaultCellStyle.Font = new Font("微軟雅黑",9, FontStyle.Bold);
            dataGridView.RowsDefaultCellStyle.Font = new Font("微軟雅黑",8.2F, FontStyle.Regular);
            dataGridView.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
            dataGridView.AllowUserToAddRows = false;//這樣預設就沒有額外的空行

            //dataGridView事件
            dataGridView.KeyUp += dataGridView_KeyUp;
            dataGridView.MouseWheel += dataGridView_MouseWheel;
            dataGridView.MouseEnter += dataGridView_MouseEnter;
            dataGridView.MouseClick += dataGridView_Click;

            //dataGridView添加兩列
            dataGridView.Columns.Add("column1", "");
            dataGridView.Columns.Add("column2", "花銷");

            //設定dataGridView各列的屬性
            dataGridView.Columns[0].Width = panel1.Width / 4;
            dataGridView.Columns[1].Width = 3*panel1.Width / 4;
            dataGridView.Columns[0].ReadOnly = true;//此列不可被使用者編輯
            dataGridView.Columns[0].SortMode = DataGridViewColumnSortMode.NotSortable;//禁止第一列排序
            dataGridView.Columns[1].SortMode = DataGridViewColumnSortMode.NotSortable;//禁止第二列排序

            //設定第一行的屬性
            dataGridView.Rows.Add("1");

            //将dataGridView添加到panel1中
            panel1.Controls.Add(dataGridView);

        }

        /// <summary>
        /// dataGridView滑鼠點選事件
        /// </summary>
        private void dataGridView_Click(object sender, MouseEventArgs e)
        {
            ContextMenuStrip strip = new ContextMenuStrip();
            strip.ShowImageMargin = false;//設定右擊菜單屬性
            strip.Items.Add("删除標明行");
            strip.Items.Add("添加行");

            strip.Items[0].Click += stripItems0_Click;//彈出菜單第一項點選事件
            strip.Items[1].Click += stripItems1_Click;//彈出菜單第二項點選事件

            if (e.Button == MouseButtons.Right)//右鍵點選
            {
                strip.Show(this.dataGridView, e.Location);//彈出菜單
            }
        }

        /// <summary>
        /// 彈出菜單第二項點選事件
        /// </summary>
        private void stripItems1_Click(object sender, EventArgs e)
        {
            rowNo++;
            dataGridView.Rows.Add(rowNo.ToString());
            if (rowNo > 15)
            {
                scrollBarMaxinum++;
                scrollBar.Maximum = scrollBarMaxinum;
            }
        }

        /// <summary>
        /// stripItem0點選事件-删除選中行
        /// </summary>
        private void stripItems0_Click(object sender, EventArgs e)
        {
            dataGridView.Rows.RemoveAt(dataGridView.CurrentRow.Index);//删除選中行

            //給第一列(編号列)重新編号
            for (int i = 0; i < dataGridView.Rows.Count; i++)
            {
                dataGridView.Rows[i].Cells[0].Value = i+1;
            }

            rowNo = dataGridView.RowCount;//使rowNo值為目前行數

            if (scrollBarMaxinum>0)
            {
                scrollBarMaxinum--;
                scrollBar.Maximum = scrollBarMaxinum;
            }
        }

        /// <summary>
        /// 滾動條滾動事件
        /// </summary>
        private void scrollBar_Scroll(object sender, ScrollEventArgs e)
        {
            if (e.NewValue>=rowNo)//若目前值不小于行号,則不執行後面代碼
            {
                return;
            }
            dataGridView.FirstDisplayedScrollingRowIndex = e.NewValue;            
        }

        /// <summary>
        /// 滑鼠進入dataGridView區域事件
        /// </summary>
        private void dataGridView_MouseEnter(object sender, EventArgs e)
        {
            scrollBar.Show();

            timer.Interval = 1000;//設定時鐘間隔為1s
            timer.Start();
            timer.Tick += timer_Tick;
        }

        /// <summary>
        /// 滑鼠離開scrollBar事件
        /// </summary>
        private void scrollBar_MouseLeave(object sender, EventArgs e)
        {
            mouseEnterScrollBar = false;
            timer.Start();
        }

        private bool mouseEnterScrollBar = false;//該值訓示滑鼠是否進入scrollBar範圍
        /// <summary>
        /// 滑鼠進入scrollBar範圍事件
        /// </summary>
        private void scrollBar_MouseEnter(object sender, EventArgs e)
        {
            mouseEnterScrollBar = true;
        }

        /// <summary>
        /// 聲明一計時工具
        /// </summary>
        private Timer timer = new Timer();
        /// <summary>
        /// 滑鼠滑輪滾動事件
        /// </summary>
        private void dataGridView_MouseWheel(object sender, MouseEventArgs e)
        {
            scrollBar.Show();
            timer.Interval = 1000;//設定時鐘間隔為1s
            timer.Start();
            timer.Tick += timer_Tick;
        }

        int count = 0;//計數,訓示目前是計時器開始後的第幾秒
        /// <summary>
        /// Timer周期事件,每1s發生一次
        /// </summary>
        private void timer_Tick(object sender, EventArgs e)
        {
            count++;
            if (count>4)
            {
                timer.Stop();
                count = 0;
                if (!mouseEnterScrollBar)
                {
                    scrollBar.Hide();
                }
            }
        }

        int rowNo = 1;//設定最後一行的編号
        int scrollBarMaxinum = 0;//scrollBar的最大值
        /// <summary>
        /// dataGridView按鍵事件
        /// </summary>
        private void dataGridView_KeyUp(object sender, KeyEventArgs e)
        {
            if(e.KeyValue==13)
            {
                rowNo++;
                dataGridView.Rows.Add(rowNo.ToString());
                if (rowNo>15)
                {
                    scrollBarMaxinum++;
                    scrollBar.Maximum = scrollBarMaxinum;
                }
            }
        }

        /// <summary>
        /// Button按鈕點選事件
        /// </summary>
        private void button1_Click(object sender, EventArgs e)
        {
            bool errorAccured = false;//此值訓示是否檢測到錯誤

            #region 輸入驗證
            for (int i = 0; i < dataGridView.RowCount; i++)
            {
                string cellValue = "";
                if (dataGridView.Rows[i].Cells[1].Value!=null)
                {
                    cellValue = dataGridView.Rows[i].Cells[1].Value.ToString();
                }
                else
                {
                    cellValue = "";
                }
                string validPattern = "^[0-9]+(.[0-9]+)?$";//比對的類型有:0,0.0,0.00...,00.0.0.00
                string inValidPattern1 = "^[0.]{2,}$";//比對的類型有:00,.. 
                string inValidPattern2 = "^0([0-9]){1,}.*$";//比對的類型有:00,000,000.,000..

                if (Regex.IsMatch(cellValue, inValidPattern1))
                {
                    dataGridView.Rows[i].Cells[1].Style.BackColor = Color.FromArgb(255, 240, 240);
                    errorAccured = true;
                }
                else
                {
                    dataGridView.Rows[i].Cells[1].Style.BackColor = Color.White;
                }

                if (Regex.IsMatch(cellValue, inValidPattern2))
                {
                    dataGridView.Rows[i].Cells[1].Style.BackColor = Color.FromArgb(255, 240, 240);
                    errorAccured = true;
                }
                else
                {
                    dataGridView.Rows[i].Cells[1].Style.BackColor = Color.White;
                }

                if (!Regex.IsMatch(cellValue, validPattern))
                {
                    dataGridView.Rows[i].Cells[1].Style.BackColor = Color.FromArgb(255, 240, 240);
                    errorAccured = true;
                }
                else
                {
                    dataGridView.Rows[i].Cells[1].Style.BackColor = Color.White;
                }
            }

            #endregion

            if (errorAccured)//檢測到錯誤則不執行後面代碼
            {
                return;
            }

            double result =0;//記錄數字結果
            resultArray = new double[dataGridView.RowCount];//聲明一double型的數組,記錄每行結果
            for (int i = 0; i < dataGridView.RowCount; i++)
            {
                result += double.Parse(dataGridView.Rows[i].Cells[1].Value.ToString());
                resultArray[i] = double.Parse(dataGridView.Rows[i].Cells[1].Value.ToString());
            }

            PersonalAccountForm.result = result;//指派

            this.Close();//關閉目前窗體
        }

        /// <summary>
        /// 窗體加載事件
        /// </summary>
        private void PersonalAccountForm_Load(object sender, EventArgs e)
        {
            if (!(resultArray is null))
            {
                dataGridView.Rows[0].Cells[1].Value = resultArray[0];
                for (int i = 1; i < resultArray.Length; i++)
                {
                    dataGridView.Rows.Add((i + 1).ToString(), resultArray[i]);//根據記錄的數組添加行
                }
            }
        }
    }