2013-04-10 63 views
2

我有WinForms DataGridView,其源設置爲SortableBindingList。在這種形式下,有Comment列,我需要阻止用戶插入一些字符,從而驗證。DataGridView - 單元驗證 - 防止CurrentRow/Cell更改

我想要做的是,每當用戶輸入無效值時,系統會通知他(OnNotification('You entered wrong comment');)並強制他/她保持編輯模式。

到目前爲止,我建立的解決方案是這樣的:

void MyDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
{ 
    if (e.ColumnIndex == ColumnComment.Index) { 
     object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value; 
     if((data != null) && (!CommentIsValid(data.ToString()))){ 
      CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex]; 
      BeginEdit(true); 

      // My notification method 
      OnNotification(String.Format("Comment `{0}` contains invalid characters)); 
      return; 
     } 
    } 
} 

我有以下這個問題:

  • OnCellValidating被觸發,只有當整個表單被關閉或噹噹前行發生改變,而不是之後我完成編輯單個單元格,所以我已將支票放入CellEndEdit
  • 當我使用Enter/Esc來結束編輯時,它按預期和想要的方式工作。
  • 當我使用鼠標並單擊另一行時,單元格保持編輯模式,但另一行被選中。
  • 當我嘗試使用Enter(顯示無效意見通知),然後Esc(取消編輯)它使用值通過Enter(因爲編輯模式已完成)。

所以我的問題是

  • 我怎麼能每個單元格編輯後火CellValidating,而不是當窗體關閉
  • 如何防止CurrentRowCurrentCell變化甚至鼠標點擊之後?
  • 如何強制單元格在編輯模式下逗留

回答

1

當我使用鼠標點擊到另一行,細胞停留在編輯模式下,但另一行被選中。

這裏我將使用全局布爾值bool isInvalidState說和全局DataGridViewCell = invalidCell對象。在默認狀態下,您可以設置isInvalidState = falseinvalidCell = null。然後,在上述方法使用

private bool OnNotification(string cellValue) 
{ 
    // Check for error. 
    if (error) 
     return false; 
} 

那麼現在

void MyDataGridView_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
{ 
    if (e.ColumnIndex == ColumnComment.Index) { 
     object data = Rows[e.RowIndex].Cells[e.ColumnIndex].Value; 
     if((data != null) && (!CommentIsValid(data.ToString()))){ 
      CurrentCell = Rows[e.RowIndex].Cells[e.ColumnIndex]; 
      BeginEdit(true); 

      // My notification method 
      isInvalidState = OnNotification(
       String.Format("Comment `{0}` contains invalid characters)); 
      if (isInvalidState) 
       invalidCell = MyDataGridView[e.RowIndex, e.ColumnIndex]; 
      return; 
     } 
    } 
} 

,線了一個事件CellContentClickDataGridView並檢查是否isInvalidState == true

private void MyDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e) 
{ 
    if (isInvlaidState) 
    { 
     isInvalidState = false; 
     MyDataGridView.CurrentCell = invalidCell; 
     invalidCell = null; 
     return; 
    } 
    // Do other stuff here. 
} 

當我嘗試使用輸入(顯示無效註釋通知),然後Esc(取消編輯),它使用由Enter推送的值(因爲使用編輯模式已完成)。

我不確定這個問題;很可能您必須處理KeyDown事件並捕獲退出鍵 - 以不同的方式處理它。

我希望這會有所幫助。

+1

不幸的是,它並沒有完全適用於我,因爲CellContentClick事件處理程序中的代碼從未將控制權設置回被驗證的單元格,儘管如此,儘管使用全局變量isInvalidState和' invalidCell'幫助我構建了另一個完美的解決方案,我將盡快在此發佈我的解決方案。 – 2017-09-05 17:09:13

0

嘗試類似這樣的事情。它應該工作。

private void datagridview1_dataGridview_CellValidating 
(object sender, DataGridViewCellValidatingEventArgs e) 
{ 
    if (datagridview1_dataGridview.Rows[e.RowIndex].Cells[2].Value.Equals("")) 
    { 
     MessageBox.Show("Product name should not be empty", "Error"); 
     datagridview1_dataGridview.CurrentCell = datagridview1_dataGridview.Rows[e.RowIndex].Cells[2]; 
     datagridview1_dataGridview.CurrentCell.Selected = true; 
    } 
} 
+0

我在我的問題中提到'OnCellValidating只有當整個窗體關閉時觸發或whe當前行被更改,而不是在完成單個單元格的編輯後,所以我已將檢查放入CellEndEdit.'中,因此無論您如何在編輯模式關閉之前啓動CellValidating,這都可行。否則它是無用的:( – Vyktor 2013-04-10 08:12:54

0

不幸的是,MoonKnight的解決方案並沒有完全適用於我,因爲CellContentClick事件處理程序中的代碼從未將控件重新設置爲當它的值爲無效值時正在驗證其值的單元。儘管如此,考慮到他使用全局變量isInvalidStateinvalidCell的有價值的提示幫助我構建了以下解決方案,該解決方案完全按照OP中的要求工作。

執行CellValidating事件處理中的數據驗證:

使用的以正確的方式CellValidatingCellValidated組合如下解決了這個問題。設置isInvalidState標誌和cellWithInvalidUserInput變量(注:我改名爲invalidCellcellWithInvalidUserInput):

private void MyDataGridView_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
{ 
    var cellUnderConsideration = MyDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex]; 

    if (!ValidateCurrentCellValue(cellUnderConsideration)) 
    {    
     OnNotification(String.Format("Comment `{0}` contains invalid characters)); 
     //Or MessageBox.Show("your custom message"); 

     isInvalidState = true; 
     cellWithInvalidUserInput = cellUnderConsideration; 
     e.Cancel = true;      
    } 
} 

的數據驗證功能:

bool isInvalidState; 
DataGridViewCell cellWithInvalidUserInput; 
private bool ValidateCurrentCellValue(DataGridViewCell cellToBeValidated) 
{ 
    //return 'true' if valid, 'false' otherwise 
} 

執行的CellValidated事件處理中的UI控件所需的操作:

private void MyDataGridView_CellValidated(object sender, DataGridViewCellEventArgs e) 
{ 
    if (isInvalidState) 
    { 
     isInvalidState = false; 

     if (cellWithInvalidUserInput != null && cellWithInvalidUserInput.RowIndex > -1) 
     { 
      MyDataGridView.CurrentCell = cellWithInvalidUserInput; 
      MyDataGridView.CurrentCell.Selected = true; 
      MyDataGridView.BeginEdit(true); 
     } 

     cellWithInvalidUserInput = null; 
    } 
}