2011-10-10 75 views
5

我想驗證Winforms datagridview單元格與單元格驗證。如果用戶設置的值不正確,我設置ErrorText並使用e.Cancel,以便光標保留在單元格中。 現在的問題是,錯誤符號(和錯誤文本)不顯示(在單元格中)。當我刪除e.Cancel時,單元格失去焦點並顯示錯誤符號。我如何實現單元格保持編輯模式並顯示錯誤符號?Winforms:驗證datagridview中單元格的問題

if (...) 
{ 
    this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext"; 
    e.Cancel = true; 
} 
else 
{ 
    this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = ""; 
} 
+0

正如我在回答說 - 你所描述是不開箱的行爲,所以你必須做一些不尋常的。你能提供一些代碼嗎? –

回答

9

您看到的行爲實際上是由於繪畫問題,而不是由於未顯示錯誤圖標。發生什麼事情是,當你設置單元格的錯誤文本時,圖標被顯示,但編輯模式下單元格的文本框被繪製在圖標上,因此沒有圖標顯示給用戶!

您有修復此兩種選擇 - 一個是簡單地使用該行的錯誤文本,以代替:

this.datagridviewX.Rows[e.RowIndex].Cells[e.ColumnIndex].ErrorText = "Errortext"; 
e.Cancel = true; 

您有:

this.datagridviewX.Rows[e.RowIndex].ErrorText = "Errortext"; 
e.Cancel = true; 

另一種選擇是改變細胞填充單元格(移動編輯控件)並繪製圖標。

我實際上發現此技術用於解決問題here並重現d代碼如下(在C#中,而不是在VB.Net中)。

首先,你必須你的驗證活動在其中添加一些代碼來更改單元格邊距:

void dataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e) 
{ 
    if (string.IsNullOrEmpty(e.FormattedValue.ToString())) 
    { 
     DataGridViewCell cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]; 

     cell.ErrorText = 
      "Company Name must not be empty"; 

     if (cell.Tag == null) 
     { 
      cell.Tag = cell.Style.Padding; 
      cell.Style.Padding = new Padding(0, 0, 18, 0); 
     } 
     e.Cancel = true; 

    } 
    else 
    { 
     dataGridView1.Rows[e.RowIndex].ErrorText = string.Empty; 
    } 
} 

這使得可以看到圖標沒有編輯控制移動,除了圖標移動呢!所以我們也需要畫一個新的圖標。

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) 
{ 
    if (dataGridView1.IsCurrentCellDirty) 
    { 
     if (!string.IsNullOrEmpty(e.ErrorText)) 
     { 
      GraphicsContainer container = e.Graphics.BeginContainer(); 
      e.Graphics.TranslateTransform(18,0); 
      e.Paint(this.ClientRectangle, DataGridViewPaintParts.ErrorIcon); 
      e.Graphics.EndContainer(container); 
      e.Handled = true; 
     } 
    } 
} 

然後,當你結束編輯的細胞,你需要重新設置填充:

void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e) 
{ 
    if (!string.IsNullOrEmpty(dataGridView1[e.ColumnIndex, e.RowIndex].ErrorText)) 
    { 
     DataGridViewCell cell = dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex]; 
     cell.ErrorText = string.Empty; 
     cell.Style.Padding = (Padding)cell.Tag; 
     cell.Tag = null; 
    } 
} 

,我發現這忽略了設置鼠標的新畫圖標後 - 下面是一些粗略的代碼解決了這個問題,我沒有時間讓它真正起作用,所以有一些想法可以解決的小問題 - 如果一分鐘後我會收拾整理。

我設置DataGridView.ShowCellToolTips = true並引入一個布爾型inError來跟蹤我們目前是否有編輯錯誤。然後處理MouseHover事件:

void dataGridView1_MouseHover(object sender, EventArgs e) 
{ 
    if (inError) 
    {     
     Point pos = this.PointToClient(Cursor.Position);    

     if (r.Contains(pos.X - 20, pos.Y - 5)) 
     {     
      t.Show("There was an error", dataGridView1.EditingControl, 3000); 
     } 
    } 
} 

該代碼中的t是表單級別的ToolTip控件,r是矩形。

我填寫如下R IN細胞繪畫處理程序:

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) 
{ 
    if (dataGridView1.IsCurrentCellDirty) 
    { 
     if (!string.IsNullOrEmpty(e.ErrorText)) 
     {    
      GraphicsContainer container = e.Graphics.BeginContainer(); 

      r = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); 
      e.Graphics.TranslateTransform(18, 0); 
      e.Paint(this.ClientRectangle, DataGridViewPaintParts.ErrorIcon); 
      e.Graphics.EndContainer(container);    

      e.Handled = true; 
     } 
    } 
} 

我不開心上的位置點負20,負5 - 這就是我要解決了,如果我有多一點時間。

+0

我正是試圖與dataGridView1.Rows [e.RowIndex] .Cells [e.ColumnIndex] .ErrorText = ... – Kottan

+0

@Kottan提供一些代碼(可能是最好的整個形式,如果不是太大),我們可以有一個看。 –

+0

@Kottan - 好的,現在就來。你的問題並沒有說清楚你是在單元格而不是行中設置錯誤。提供代碼總是一件好事。 –