C# Winform
自定義 DataGridView
附源碼-最終版
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]);//根據記錄的數組添加行
}
}
}
}