在 DataGridView 內根據條件來決定 DataGridViewCell 唯讀、可編輯。
該範例會在 CellBeginEdit 事件內,根據 [結案] 欄位資料,來決定 [價格] 欄位是否唯讀,並在CellFormatting 事件內,把唯讀的 Column、Cell 設定為淺灰色方便識別。
UI 設計
C# Code
在 CellBeginEdit 事件內,把 把 DataGridViewCellCancelEventArgs.Cancel 設定為 true 即取消編輯該 cell,就可以達到唯讀效果。
namespace CellEditableCore
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.AutoGenerateColumns = false;
// 把 ColNO 設為唯讀
ColNO.ReadOnly = true;
ColNO.DefaultCellStyle.BackColor = Color.LightGray;
}
private void Form1_Load(object sender, EventArgs e)
{
List<Data> source = new List<Data>();
source.Add(new Data() { NO = "001", Price = 100, Done = true });
source.Add(new Data() { NO = "002", Price = 789, Done = false });
source.Add(new Data() { NO = "003", Price = 500, Done = true });
source.Add(new Data() { NO = "004", Price = 1000, Done = false });
source.Add(new Data() { NO = "005", Price = 2000, Done = true });
dataGridView1.DataSource = source;
}
private void dataGridView1_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
if (e.ColumnIndex != ColPrice.Index)
return;
bool done = (bool)dataGridView1.Rows[e.RowIndex].Cells[ColDone.Index].Value;
// 把 e.Cancel = true 即取消編輯該 cell
e.Cancel = done;
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex != ColPrice.Index)
return;
bool done = (bool)dataGridView1.Rows[e.RowIndex].Cells[ColDone.Index].Value;
e.CellStyle.BackColor = done ? Color.LightGray : dataGridView1.DefaultCellStyle.BackColor;
}
}
public class Data
{
[Description("編號")]
public string NO { get; set; }
[Description("價格")]
public decimal Price { get; set; }
[Description("結案")]
public bool Done { get; set; }
}
}
執行結果自動生成欄位
預設拉一個 DataGridView 來使用,AutoGenerateColumns 預設為 true,忘記把它設定為 false,導致在 CellBeginEdit 和 CellFormatting 事件內鬼打牆,在 CellFomatting 內寫個簡單範例來說明
bool trigger = false;
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (trigger == false)
{
foreach (DataGridViewColumn col in dataGridView1.Columns)
textBox1.Text += $"ColumnName:{col.Name}-ColumnIndex:{col.Index}" + Environment.NewLine;
textBox2.Text += $"ColNO:{ColNO.Index}" + Environment.NewLine;
textBox2.Text += $"ColPrice:{ColPrice.Index}" + Environment.NewLine;
textBox2.Text += $"ColDone:{ColDone.Index}" + Environment.NewLine;
}
trigger = true;
}
從下圖可以看見,AutoGenerateColumns = true 情況下,[直接顯示 ColumnIndex] 會全部都是 0,造成欄位判斷異常,永遠都是第一欄位的背景顏色變化


沒有留言:
張貼留言