[英]CurrentCellDirtyStateChanged doesn't work after a datagridview error C#
我有一個datagridview從數據庫加載數據。 該datagridview有2個int列,我在其中插入數字。 而且,如果我在兩列之一中插入數字,那么還會有另外兩列單元格自動填充數學運算的結果。 相反,如果我插入字母,則datagridview會顯示錯誤。
問題是:每當datagridview給我顯示錯誤時,在錯誤消息框中單擊“確定”后,我可以繼續編輯單元格,但是CurrentCellDirtyStateChanged事件不起作用。 因此,其他兩列單元格不會自動填充。 在顯示錯誤之后,我需要它們自動填充。
這是我的代碼:
private void dgvReciboPagoSalario_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
e.ThrowException = false;
string Error = "Error: La columna " +
dgvReciboPagoSalario.Columns[e.ColumnIndex].HeaderText +
" es de tipo numérico";
DialogResult DR= MessageBox.Show(Error, "Error",
MessageBoxButtons.OK, MessageBoxIcon.Error);
e.Cancel = false;
}
這是CurrentCellDirtyStateChanged事件:
private void dgvReciboPagoSalario_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{//modificar campos de dgv al mismo tiempo que cambio otro
int HO = 0;
int HF = 0;
long SXH = 0;
long Subtotal = 0;
long DeduccionesPrestamo = 0;
long DeduccionesCCSS = 0;
long Total = 0;
if (dgvReciboPagoSalario.IsCurrentCellDirty)
{
dgvReciboPagoSalario.CommitEdit(DataGridViewDataErrorContexts.Commit);
if (!string.IsNullOrEmpty(dgvReciboPagoSalario.CurrentRow.Cells["Horas Ordinarias"].Value.ToString()))
{
HO = Convert.ToInt32(dgvReciboPagoSalario.CurrentRow.Cells["Horas Ordinarias"].Value);
}
if (!string.IsNullOrEmpty(dgvReciboPagoSalario.CurrentRow.Cells["Horas Feriado"].Value.ToString()))
{
HF = Convert.ToInt32(dgvReciboPagoSalario.CurrentRow.Cells["Horas Feriado"].Value);
}
SXH = Convert.ToInt64(dgvReciboPagoSalario.CurrentRow.Cells["Salario por Hora"].Value);
Subtotal = ((HO * SXH) + ((SXH * 2) * HF));
dgvReciboPagoSalario.CurrentRow.Cells["Subtotal Recibido"].Value = Subtotal;
if (!string.IsNullOrEmpty(dgvReciboPagoSalario.CurrentRow.Cells["Deducciones Préstamo"].Value.ToString()))
{
DeduccionesPrestamo = Convert.ToInt64(dgvReciboPagoSalario.CurrentRow.Cells["Deducciones Préstamo"].Value);
}
DeduccionesCCSS = Convert.ToInt64(dgvReciboPagoSalario.CurrentRow.Cells["Deducciones CCSS"].Value);
Total = (Subtotal - (DeduccionesCCSS + DeduccionesPrestamo));
dgvReciboPagoSalario.CurrentRow.Cells["Total Recibido"].Value = Total;
}
提前致謝!。
從發布的代碼看來,正在使用CurrentCellDirtyStateChanged
事件從其他列中的值設置Total Recibido
列。 這將起作用,但是,如果您要使用DataTable
並將Total Recibido
列設置為表中當前單元格的Expression
,則不需要CurrentCellDirtyStateChanged
事件來處理此問題。
例如,按照發布的代碼並使用DataTable
, Total Recibido
列的可能Expression
如下所示。 添加的最后一列是“ Total
列的“ Expression
”。
private DataTable GetDT() {
DataTable dt = new DataTable();
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("OrdinaryHours", typeof(double));
dt.Columns.Add("HourlyWage", typeof(double));
dt.Columns.Add("HolidayHours", typeof(double));
dt.Columns.Add("CCSSDeductions", typeof(double));
dt.Columns.Add("LoanDeductions", typeof(double));
DataColumn dc = new DataColumn("Total", typeof(double));
dc.Expression = "((OrdinaryHours * HourlyWage) + (HourlyWage * 2) * HolidayHours) - (CCSSDeductions + LoanDeductions)";
dt.Columns.Add(dc);
return dt;
}
將以上DataTable
與Expression
列用於Total
可以消除對CurrentCellDirtyStateChanged
事件的需要。 在所有其他單元格都有數據之后, Total
s列單元格將自動更新。
此外,從帖子中看來,您沒有捕獲此DataError
,這是恕我直言的問題。 由於所討論的列是數字類型(int,double..etc),因此,當用戶鍵入字符而不是數字並嘗試離開單元格時,將引發DataError
。
我猜想,如果您“捕獲”用戶的KeyPressed
事件並直接忽略任何無效字符,則可能會更輕松,更友好。 示例:如果捕獲到用戶KeyPressed
輸入,並且該輸入位於應為數字且不是數字或小數點的列之一中,則忽略該輸入。 使用此實現,用戶將無法鍵入數字和小數點以外的字符。 這將防止DataError
被那些列拋出。
為此,您需要為目標列中的單元格實施一個“ KeyPressed”事件。 觸發此事件時,它可以檢查並忽略任何無效字符。 需要連接的事件是DataGridViews
EditingControlShowing
事件。 用戶鍵入單元格時將觸發此事件。 首先,檢查用戶鍵入的單元格是否在數字列之一中。 如果是,那么您只需要向該單元格注冊KeyPressed
事件。 然后將觸發KeyPressed
事件,您可以檢查正確的字符值。
下面是此KeyPressed
事件的外觀示例。
private void DoubleColumn_KeyPress(object sender, KeyPressEventArgs e) {
// if the key pressed is not a control key or a digit or decimal - then ignore this character
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.') {
e.Handled = true;
}
// check for multiple decimal points as only one is valid
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1) {
e.Handled = true;
}
}
然后,要使用此事件,當用戶鍵入數字列單元格時,我們只需在單元格中注冊事件。 此事件是EditingControlShowing
事件。 在這種情況下,將檢查它是否為數字列,然后注冊KeyPressed
事件以對該單元觸發。
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
e.Control.KeyPress -= new KeyPressEventHandler(DoubleColumn_KeyPress);
if (dataGridView1.CurrentCell.ColumnIndex == 1 || dataGridView1.CurrentCell.ColumnIndex == 2 ||
dataGridView1.CurrentCell.ColumnIndex == 3 || dataGridView1.CurrentCell.ColumnIndex == 4 ||
dataGridView1.CurrentCell.ColumnIndex == 5) {
e.Control.KeyPress += new KeyPressEventHandler(DoubleColumn_KeyPress);
}
}
無論DataGridView
是否與數據綁定,以上兩種方法均應起作用。 希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.