网格排序时 DataGridView.CellFormatting 不起作用

发布于 2024-12-01 03:24:54 字数 1814 浏览 4 评论 0原文

我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

节枝 2024-12-08 03:24:54

我建议您尝试 RowPrePaint 因为它可以让您在绘制任何内容之前但在数据绑定之后更改表格。

I suggest you try RowPrePaint as it lets you alter the table before it paints anything but after it has databound it.

优雅的叶子 2024-12-08 03:24:54
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

结束子

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

夜访吸血鬼 2024-12-08 03:24:54

您的问题是 DataGridView.CellFormatting 是一个单元格级事件,但您使用它来格式化整行。

CellFormatting 会针对每个可见单元格触发,并且对于您要重新格式化整行的每个单元格(通过 CurrentRow.DefaultCellStyle),然后为重新格式化的单元格触发更多单元格格式化事件细胞。这可能会产生一个从内部转义的事件循环,但它会为您提供一个虚假的 RowIndex 值。

如果您将代码更改为仅重新设置相关单元格的样式,您的问题将会消失

Dim currentCell As DataGridViewCell = CurrentRow(e.ColumnIndex)

Select Case UCase(strTestValue)
    Case "WARNING"
        currentCell.Style.BackColor = Color.PeachPuff
    Case "ERRMESSAGE"
        currentCell.Style.BackColor = Color.Salmon
End Select

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 (via CurrentRow.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 for RowIndex.

If you change your code to only restyle the relevant cell, your problem will disappear:

Dim currentCell As DataGridViewCell = CurrentRow(e.ColumnIndex)

Followed by:

Select Case UCase(strTestValue)
    Case "WARNING"
        currentCell.Style.BackColor = Color.PeachPuff
    Case "ERRMESSAGE"
        currentCell.Style.BackColor = Color.Salmon
End Select
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文