使用LINQ从DataView检索行索引

时间:2013-09-06 13:46:20

标签: vb.net linq datagridview formatting dataview

我的DataView的Table属性被分配给我的一个DataTables。然后将DataView设置为我的DataGridView的DataSource。像这样:

View.Table = DataSet1.Tables("dtArticles")
dgvArticles.DataSource = View

我的目标是在某些给定的行上执行一些格式化。不幸的是,我发现这样做的唯一方法是使用CellFormatting事件。这很长,因为它必须遍历每一行并验证行是否需要一些格式(粗体字,背景色)。

CellFormatting

Private Sub dgvArticles_CellFormatting(sender As Object, e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgvArticles.CellFormatting
    Dim drv As DataRowView
    If e.RowIndex >= 0 Then
        If e.RowIndex <= DataSet1.Tables("dtArticles").Rows.Count - 1 Then
            drv = View.Item(e.RowIndex)
            Dim c As Color

            'Bolds if it is standard, makes it regular if it's not standard and already bold
            If drv.Item("Standard").ToString = "Yes" Then
                dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font = New Font("Microsoft Sans Sherif", 8, FontStyle.Bold)
            End If

            'Test if Standard is "No" and if the row is currently bold, if it is, put it back to regular
            If drv.Item("Standard").ToString = "No" And Not dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font Is Nothing Then
                If dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font.Bold Then
                    dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font = New Font("Microsoft Sans Sherif", 8, FontStyle.Regular)
                End If
            End If

            'Puts a red color to the rows who are not available
            If drv.Item("Available").ToString = "No" Then
                'Change back color
                c = Color.LightSalmon
                e.CellStyle.BackColor = c
            End If
        End If
    End If
End Sub

这对于添加到DataGridView的每一行单元格的作用是什么;它检查我的Standard列的当前值是否等于是或否。根据结果,它将粗体/非粗体显示该行。同一主要内容适用于我的Available列。如果可用值等于“否”,那么我将浅红色背面颜色添加到该行。此事件多次引发(10,000篇文章,DataTable为10个左右)。

平均约2.2-2.7秒


迭代DataView

Dim i As Integer = 0
For Each dt As BillMat.dtArticlesRow In View.Table.Rows
    If dt.Standard = "Oui" Then dgvArticles.Rows(i).DefaultCellStyle.Font = New Font("Microsoft Sans Sherif", 8, FontStyle.Bold)
    If dt.Available = "Non" Then dgvArticles.Rows(i).DefaultCellStyle.BackColor = Color.LightSalmon
    i += 1
Next

平均约1.5-1.7秒


是否可以使用LINQ选择Standard列等于“是”且哪个Available列等于“否”的RowIndex?如果是,不会使用索引来应用格式比迭代整个10,000篇文章快得多吗?

1 个答案:

答案 0 :(得分:1)

我不知道使用Link是否是解决问题的最佳方案。

您应该首先尝试简化DataGridView.CellFormatting事件中的代码。一些可能的方式:

  • 创建常规和粗体字体一个私有实例,以避免在方法中创建多个实例
  • 我想如果第一个条件通过,你不需要测试第二个条件。因此,If End If + If End If可以替换为If Else End If(不需要测试这两个表达式)
  • 使用If x AndAlso y Then代替If x And y Then:如果第一个表达式为false,则第二个表达式不会被测试
  • 我不明白这个If e.RowIndex <= DataSet1.Tables("dtArticles").Rows.Count - 1 Then的目的。如果目标不是测试,如果行是 NewRow AllowUserToAddRows属性设置为True),那么简化就是

    If DataGridView1.Rows(e.RowIndex).IsNewRow then
    

Private _RegularFont As New Font("Microsoft Sans Sherif", 8, FontStyle.Regular)
Private _BoldFont As New Font("Microsoft Sans Sherif", 8, FontStyle.Bold)

Private Sub dgvArticles_CellFormatting(sender As Object, e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles dgvArticles.CellFormatting
    Dim drv As DataRowView
    If e.RowIndex >= 0 Then
        If Not dgvArticles.Rows(e.RowIndex).IsNewRow Then
            drv = View.Item(e.RowIndex)

            'Bolds if it is standard, makes it regular if it's not standard and already bold
            If drv.Item("Standard").ToString = "Yes" Then
                dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font = _BoldFont
            Else 'First condition tested, test second 

                'Test if Standard is "No" and if the row is currently bold, if it is, put it back to regular
                If drv.Item("Standard").ToString = "No" AndAlso Not dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font Is Nothing Then
                    If dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font.Bold Then
                        dgvArticles.Rows(e.RowIndex).DefaultCellStyle.Font = _RegularFont
                    End If
                End If
            End If

            'Puts a red color to the rows who are not available
            If drv.Item("Available").ToString = "No" Then
                'Change back color
                Dim c As Color
                c = Color.LightSalmon
                e.CellStyle.BackColor = c
            End If
        End If
    End If
 End Sub

使用链接,您可以执行以下操作(出于您的目的,您不应该迭代到DataView.Rows来检索索引,而是直接在DataGridView.Rows中):

Dim _BoldFont As New Font("Microsoft Sans Sherif", 8, FontStyle.Regular)

Dim q = From r In Me.DataGridView1.Rows 
        Where CType(r, DataGridViewRow).Cells("Standard").Value.ToString = "Oui" 
        Select r
For Each item In q
        CType(item, DataGridViewRow).DefaultCellStyle.Font = _BoldFont
Next

Dim q = From r In Me.DataGridView1.Rows 
        Where CType(r, DataGridViewRow).Cells("Available").Value.ToString = "Non" 
        Select r
For Each item In q
        CType(item, DataGridViewRow).DefaultCellStyle.BackColor = Color.LightSalmon
Next