該差異導致移轉新系統後,使用者操作上不順暢,常常莫名就會新增資料至 DataGridView 內去,需要手動去刪除空白資料,就是會要求儲存時自動把空白資料刪除,特地去找出解法,讓 C# Mouse Click 事件只會在非 DisplayedRow 上觸發,減少這類無意義 feedback
DisplayedRow 名詞介紹
是從 C# DataGridView 看來,直接看圖較直白
DataGridView 上顯示的資料筆數,透過 includePartialRow 參數來決定是否抓取顯示不完整的 Row,以下圖為例,false 是抓到兩筆,true 則為三筆
抓取 DataGridView 上顯示第一筆 Row 的 RowInde,以下圖為例,會抓到編號 5 資料的 RowIndex
自訂 DataGridView
該筆記是在 MouseDown 事件並建立 InsertNewDataRow Event 來進行改寫,實務上就根據需求,看要在哪個 Mouse Click 事件內處理,也可以把整個 Mouse Click 事件都覆寫掉,那也就不需要特別去建立事件來觸發
該寫法個重點
- 點擊在 ColumnHeader 時不觸發
- 點擊在 RowHeader 時不觸發
- 點擊在非 DisplayedRow 區域時觸發
- ScrollBar 出現時,ScrollBar 必須在最下方時觸發
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace UCDataGridViewMouseDown
{
public class UCDataGridView : DataGridView
{
[Description("點擊 DataGridView 非 DisplayedRow 區域時觸發")]
public event EventHandler InsertNewDataRow;
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
int displayRowCount = DisplayedRowCount(false);
int rowHeightIncludeHeaderHeight = ColumnHeadersHeight + (RowTemplate.Height * displayRowCount);
bool isClickInRowHeader = RowHeadersWidth > e.X;
bool isClickInColumnHeader = ColumnHeadersHeight >= e.Y;
bool isClickInNonDisplayedRow = rowHeightIncludeHeaderHeight < e.Y;
if (isClickInRowHeader ||
isClickInColumnHeader)
return;
VScrollBar vScrollBar = Controls.OfType<VScrollBar>().First();
int rowIndexMax = RowCount - 1;
// DataGridView 畫面上第一筆資料的 RowIndex 加上 畫面上資料筆數
int indexStat = FirstDisplayedScrollingRowIndex + displayRowCount;
bool isScrolBottom = indexStat > rowIndexMax;
if (isClickInNonDisplayedRow && (
RowCount == 0 ||
vScrollBar.Visible == false ||
(vScrollBar.Visible == true && isScrolBottom)))
InsertNewDataRow?.Invoke(this, e);
}
}
}
把自訂控件拉進 Form 內使用
using System;
using System.Data;
using System.Windows.Forms;
namespace UCDataGridViewMouseDown
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.AllowUserToAddRows = false;
dataGridView1.AutoGenerateColumns = false;
dataGridView1.InsertNewDataRow += DataGridView1_InsertNewDataRow;
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Rows.Add(1, "姓名一");
dt.Rows.Add(2, "姓名二");
dt.Rows.Add(3, "姓名三");
dt.Rows.Add(4, "姓名四");
dt.Rows.Add(5, "姓名五");
dt.Rows.Add(6, "姓名六");
dataGridView1.DataSource = dt;
}
private void DataGridView1_InsertNewDataRow(object sender, EventArgs e)
{
MessageBox.Show(nameof(UCDataGridView.InsertNewDataRow));
}
}
}
沒有留言:
張貼留言