【问题标题】:change color of every datagridview row containing a certain value更改包含某个值的每个 datagridview 行的颜色
【发布时间】:2016-06-20 23:22:25
【问题描述】:

这可能吗?我目前正在做的只是循环遍历每一行以更改颜色,但这非常慢,因为我也在运行查询并根据结果更改颜色。这是一个例子

Part No | Other Columns
-----------------------
Part A  | 123456
Part B  | 123456
Part C  | 123456
Part A  | 123456
Part A  | 123456

我的查询在哪里是Where Part_No = 'Part A',使用我当前的方法我只会运行相同的查询 3 次。我想要做的是获取第一列的不同值,检查查询中的值并更改包含该值的行的颜色。

【问题讨论】:

  • dgv 是否绑定到数据表之类的东西?如果 WHERE 子句是 Part_No = 'Part A' B 和 C 部分在里面做什么?
  • @Plutonix 抱歉,我想还不清楚。是的,datagridview 绑定到数据源。我提到的 where 子句是在我遍历每一行时用于查询的。

标签: vb.net visual-studio-2008 datagridview


【解决方案1】:

在这里回答:How to change row color in datagridview?

===

我只是在调查这个问题(所以我知道这个问题是在大约 3 年前发布的,但也许它会对某人有所帮助......)但似乎更好的选择是将代码放在 RowPrePaint 中事件,这样您就不必遍历每一行,只需遍历那些被绘制的行(因此它在大量数据上的表现会更好: 附加到活动中

this.dataGridView1.RowPrePaint 
    += new System.Windows.Forms.DataGridViewRowPrePaintEventHandler(
        this.dataGridView1_RowPrePaint);
The event code

private void dataGridView1_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
    if (Convert.ToInt32(dataGridView1.Rows[e.RowIndex].Cells[7].Text) < Convert.ToInt32(dataGridView1.Rows[e.RowIndex]..Cells[10].Text)) 
    {
        dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Beige;
    }
}

【讨论】:

    【解决方案2】:

    一种经济的方法是使用CellFormatting 事件。这将在该单元格第一次显示时触发。它只会针对可见行触发,因此应该更快。

    Then I loop through the grid view to do something like update the data of all colored rows

    如果数据来自 db(OP 提到了查询),您应该像数据源一样对数据进行操作。 DGV 只是用户对数据的看法。与其作用于某种颜色的行,不如作用于零件编号或决定颜色的任何东西。您还可以使用此或那个零件号创建记录视图,并对其进行操作/循环以简化流程。

    由于数据可以更改,您需要处理 2 个事件:CellFormattingCellValueChanged

    Private Sub dgv1_CellFormatting(...) Handles dgv1.CellFormatting
        ' default start up color
        If e.ColumnIndex = 3 Then
            e.FormattingApplied = ColorMyRow(e.RowIndex, e.ColumnIndex)
        Else
            e.FormattingApplied = False
        End If
    End Sub
    
    Private Sub dgv1_CellValueChanged(...) Handles dgv1.CellValueChanged
        ' if the target cell changes, update
        If e.ColumnIndex = 3 Then
            ColorMyRow(e.ColumnIndex, e.RowIndex)
        End If
    End Sub
    
    ' DRY
    Private Function ColorMyRow(rowIndex As Int32, colIndex As Int32) As Boolean
        Dim bass As Color = Color.PeachPuff
        Dim pike As Color = Color.SeaShell
        Dim salmon As Color = Color.Salmon
    
        Select Case dgv1.Rows(rowIndex).Cells(colIndex).Value.ToString
            Case "Bass"
                dgv1.Rows(rowIndex).DefaultCellStyle.BackColor = bass
                Return True
            Case "Pike"
                dgv1.Rows(rowIndex).DefaultCellStyle.BackColor = pike
                Return True
            Case "Salmon"
                dgv1.Rows(rowIndex).DefaultCellStyle.BackColor = salmon
                Return True
        End Select
    
        Return False
    End Function
    

    无论 a) 用户编辑单元格,b) 您更改单元格值 (dgv1.Rows(0).Cells(3).Value = "Mermaid") 或 c) 您更改数据源 (dtParts.Rows(0)(3) = "Pike"),颜色都会更新。

    最后,您可以查询DataSource,而不是尝试在蓝色行上循环,在本例中为DataTable

    Dim bassRows = dtSample.Select("Fish = 'Bass'")
    For Each dr As DataRow In bassRows
        dr("Fish") = "Pike"
    Next
    

    颜色会自动改变。

    【讨论】:

    • 抱歉,回复晚了,还没来得及尝试这个,但既然你提到这只会为显示的行着色,如果我循环遍历 datagridview,这将如何工作,我做什么将取决于行的颜色。
    • 没有必要循环任何东西。循环遍历所有行 - 其中许多是不可见的(并且可能永远不会)是导致它变慢的原因。当每一行滚动到视图中时,将触发事件并设置背景颜色。您所做的不应该取决于颜色,而是用于设置颜色的相同决定因素。
    • 我的意思是设置颜色后循环。假设我使用你的方法,一些显示的行现在是彩色的。然后我遍历网格视图来执行类似更新所有彩色行的数据之类的操作,这些行是否不可见但假设是彩色的被更新?
    • 你没有提到任何关于数据变化的事情;仍然在 dgv 行上循环是次优的:如果数据来自数据库,您应该对数据(数据源)而不是用户的视图进行操作。已编辑。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 2021-04-06
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-10
    相关资源
    最近更新 更多