网格排序时 DataGridView.CellFormatting 不起作用
我有一个 datagridview 控件,我需要根据每行中一个单元格中的值对行进行着色。我正在使用 CellFormatting 事件,如下所示:
Private Sub DGDisplay_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgDisplay.CellFormatting
Dim intRowIndex As Integer = e.RowIndex 'This is zero when sorting.....
Dim CurrentRow As DataGridViewRow = dgDisplay.Rows(intRowIndex)
Dim strTestValue As String = CurrentRow.Cells("Status").Value
Select Case UCase(strTestValue)
Case "WARNING"
CurrentRow.DefaultCellStyle.BackColor = Color.PeachPuff
Case "ERRMESSAGE"
CurrentRow.DefaultCellStyle.BackColor = Color.Salmon
End Select
End Sub
当网格加载和滚动它等时,这工作正常。但是当我单击列标题对网格进行排序时,e.RowIndex 始终为零,并且所有行都得到第一行的格式...
为什么当网格排序时这不起作用?
编辑: Joakim 的方向是正确的,但以下代码可以正常工作:
Private Sub dgDisplay_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles dgDisplay.CellPainting
If e.RowIndex < 0 Then
Exit Sub
End If
Dim intRowIndex As Integer = e.RowIndex
Dim CurrentRow As DataGridViewRow = dgDisplay.Rows(intRowIndex)
Dim strTestValue As String = CurrentRow.Cells("Status").Value
Select Case UCase(strTestValue)
Case "WARNING"
CurrentRow.DefaultCellStyle.BackColor = Color.PeachPuff
Case "ERRMESSAGE"
CurrentRow.DefaultCellStyle.BackColor = Color.Salmon
End Select
End Sub
由于某种原因,e.RowIndex 在这里设置正确,但在其他方法上设置不正确。这里你唯一需要担心的是它可能是-1。但当我尝试使用其他方法(包括 PrePaint)时,我不得不处理它总是在排序中出现零的情况。如果我排除零情况,就像我排除负一个情况一样,那么第一行始终是白色!疯狂...我不知道为什么会这样,但确实如此。除了我使用 CellFormatting 事件得到的闪烁之外,它也不会产生任何闪烁。
如果任何人都可以解释 e.RowIndex 行为如此奇怪的原因或提供更好的方法,他们将得到公认的答案!
I have a datagridview control that where I need to color the rows based on a value in one of the cells in each row. I'm using the CellFormatting event like so:
Private Sub DGDisplay_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgDisplay.CellFormatting
Dim intRowIndex As Integer = e.RowIndex 'This is zero when sorting.....
Dim CurrentRow As DataGridViewRow = dgDisplay.Rows(intRowIndex)
Dim strTestValue As String = CurrentRow.Cells("Status").Value
Select Case UCase(strTestValue)
Case "WARNING"
CurrentRow.DefaultCellStyle.BackColor = Color.PeachPuff
Case "ERRMESSAGE"
CurrentRow.DefaultCellStyle.BackColor = Color.Salmon
End Select
End Sub
This works fine when the grid loads and when I scroll it, etc. But when I click on the column headers to sort the grid, e.RowIndex is always zero and all of the rows get the formatting of the first row...
Why isn't this working when the grid sorts?
EDIT:
Joakim was on the right track but the following code works correctly:
Private Sub dgDisplay_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles dgDisplay.CellPainting
If e.RowIndex < 0 Then
Exit Sub
End If
Dim intRowIndex As Integer = e.RowIndex
Dim CurrentRow As DataGridViewRow = dgDisplay.Rows(intRowIndex)
Dim strTestValue As String = CurrentRow.Cells("Status").Value
Select Case UCase(strTestValue)
Case "WARNING"
CurrentRow.DefaultCellStyle.BackColor = Color.PeachPuff
Case "ERRMESSAGE"
CurrentRow.DefaultCellStyle.BackColor = Color.Salmon
End Select
End Sub
For some reason, e.RowIndex is set correctly here but not on the other methods. The only thing you have to worry about here is it can be -1. But when I tried to use other methods, including PrePaint, I had to deal with it always coming up zero on a sort. If I exclude the zero case, like I excluded the negative one case about, then the first row is always white!!! Madness... I'm not sure why this works, but it does. It also produces no flicker beyond what I got using the CellFormatting event.
IF ANYONE CAN EXPLAIN THE REASON WHY e.RowIndex IS BEHAVING SO WEIRD OR OFFER A BETTER WAY OF DOING THIS THEY WILL GET THE ACCEPTED ANSWER!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我建议您尝试
RowPrePaint
因为它可以让您在绘制任何内容之前但在数据绑定之后更改表格。I suggest you try
RowPrePaint
as it lets you alter the table before it paints anything but after it has databound it.结束子
End Sub
您的问题是
DataGridView.CellFormatting
是一个单元格级事件,但您使用它来格式化整行。CellFormatting
会针对每个可见单元格触发,并且对于您要重新格式化整行的每个单元格(通过CurrentRow.DefaultCellStyle
),然后为重新格式化的单元格触发更多单元格格式化事件细胞。这可能会产生一个从内部转义的事件循环,但它会为您提供一个虚假的RowIndex
值。如果您将代码更改为仅重新设置相关单元格的样式,您的问题将会消失
:
Your problem is that
DataGridView.CellFormatting
is a cell-level event, but you're using it to format the whole row.CellFormatting
is triggered for every visible cell, and for each cell you're reformatting the entire row (viaCurrentRow.DefaultCellStyle
), which then triggers more cell formatting events for the reformatted cells. This probably produces an event loop which is being escaped from internally, but which gives you a bogus value forRowIndex
.If you change your code to only restyle the relevant cell, your problem will disappear:
Followed by: