2013-01-01 57 views
2

我在DataGridView中顯示小時數列表,並希望遮蔽那些在工作時間之外的小時。我正在嘗試使用CellPainting來做到這一點,但是我得到了奇怪的結果。有人能解釋我在這裏做錯了嗎?DGV CellPainting表現出色意外

private void dgvItemView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) 
{ 
    switch (_formType) 
    { 
     case FormType.DayView: 
      TimeSpan openTime = iFlow.Properties.Settings.Default.BusinessHourOpen; 
      TimeSpan closeTime = iFlow.Properties.Settings.Default.BusinessHourClose; 

      DataGridViewCell cell = this.dgvItemView[e.ColumnIndex, e.RowIndex]; 

      if (cell.RowIndex < openTime.Hours || cell.RowIndex > closeTime.Hours) 
      { 
       e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(25, Color.Red)), e.ClipBounds); 
      } 
      break; 
    } 
} 

但是這個代碼產生漸變效果,如下:

Form

,我真的不明白。當我上下滾動時,陰影也會消失並重新出現,這取決於我滾動多少。

那麼有人可以請解釋我在這裏做錯了嗎?如果工作時間不是一個小時,我還需要繪製部分區塊。 08:45到17:30,所以我不能只改變單元格的BackColor來實現這一點。

回答

2

e.ClipBounds指的是DataGridView的整個可見部分。
你實質上是在整個可見的DataGridView區域上繪製多個透明圖層,在滾動時產生漸變效果。

您應該使用e.CellBounds來代替。

另一個與您的問題無關的問題是您正在泄漏來自SolidBrush的GDI句柄。您SolidBrushDispose()畫,或更好,但之後,使用using語句,例如:

using (var sb = new SolidBrush(Color.FromArgb(25, Color.Red))) 
{ 
    e.Graphics.FillRectangle(sb , e.CellBounds); 
} 

編輯:

,還必須設置e.Handledtrue後塗抹,防止系統畫過你的工作。

MSDN

如果手動油漆細胞中,HandledEventArgs.Handled 屬性設置爲true。如果您未將HandledEventArgs.Handled設置爲true,則該單元格將繪製您的自定義項。

+0

謝謝,我以爲我找了一個單元格邊界,但顯然不是很好。我已將其更改爲CellBounds,並且現在完全沒有紅細胞,儘管它們在滾動時偶爾閃爍紅色。我也檢查過這個代碼只是被調用一次,它就是這樣。就好像另一個事件正在重新繪製細胞? – CrazyHorse

+0

@CrazyHorse請參閱編輯。 – Rotem

+0

完美,非常感謝您的幫助! – CrazyHorse