DataGridView添加汇总行最佳解决方案

新建1个类:

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Windows.Forms
Imports System.Data
Imports System.Drawing
Imports System.ComponentModel

Namespace OtherTools
Class DataGridViewAddSumRow
Private dgv As DataGridView = Nothing
Private dt As DataTable = Nothing
Private sc As String() = Nothing

Public Sub New()
End Sub
'
''' <summary>
''' 设置表格的数据源
''' </summary>
Public WriteOnly Property dataTableName() As DataTable
Set(ByVal value As DataTable)
Me.dt = value
End Set
End Property
'
''' <summary>
'''传递表格的名称
''' </summary>
Public WriteOnly Property DgvName() As DataGridView
Set(ByVal value As DataGridView)
dgv
= value
End Set
End Property

Public WriteOnly Property SortColsName() As String()
Set(ByVal value As String())
sc
= value
End Set
End Property
'
''' <summary>
''' 开始添加合计行
''' </summary>
Public Sub begin()
initDgv()
End Sub
Private Sub initDgv()
If dgv IsNot Nothing Then

AddHandler Me.dgv.DataSourceChanged, AddressOf dataGridView_DataSourceChanged
AddHandler Me.dgv.ColumnHeaderMouseClick, AddressOf dataGridView_ColumnHeaderMouseClick
AddHandler Me.dgv.CellValueChanged, AddressOf dataGridView_CellValueChanged
AddHandler Me.dgv.RowPostPaint, AddressOf dataGridView_RowPostPaint
Me.dgv.AllowUserToAddRows = False
dgv.DataSource
= dt
End If
End Sub
'
''' <summary>
''' 计算合计算
''' </summary>
''' <param name="dgv">要计算的DataGridView</param>
Private Sub SumDataGridView(ByVal dgv As DataGridView, ByVal sortcols As String())
If dgv.DataSource Is Nothing Then
Exit Sub
End If
'DataTable dt = (DataTable)dgv.DataSource;
If dt.Rows.Count < 1 Then
Exit Sub
End If
Dim tal As Decimal() = New Decimal(dt.Columns.Count - 1) {}
Dim font As New Font(dgv.ColumnHeadersDefaultCellStyle.Font.FontFamily, dgv.ColumnHeadersDefaultCellStyle.Font.Size, FontStyle.Bold)
Dim ndr As DataRow = dt.NewRow()

'Dim talc As String = ""

Dim number As Integer = 0
For Each dr As DataRow In dt.Rows
'dr("@xu.Hao") = System.Math.Max(System.Threading.Interlocked.Increment(number), number - 1)
Dim n As Integer = 0
For Each dc As DataColumn In dt.Columns


'If talc = "" AndAlso dc.DataType.Name.ToUpper().IndexOf("STRING") >= 0 Then
' talc = dc.ColumnName
'End If
If Array.IndexOf(Of String)(sortcols, dc.ColumnName) = -1 Then
n
+= 1
Continue For
End If

If dc.DataType.IsValueType Then
Dim hej As String = dr(dc.ColumnName).ToString()
Try
If hej <> String.Empty Then
tal(n)
+= Decimal.Parse(hej)
End If
Catch generatedExceptionName As Exception
'if (hej != string.Empty) tal[n] += decimal.Parse(hej);
End Try
End If


n
+= 1
Next
Next

ndr.BeginEdit()
For i As Integer = 0 To dt.Columns.Count - 1
If tal(i) <> 0 Then
ndr(i)
= tal(i)
End If
Next

'If talc <> "" Then
' ndr(talc) = "合计"
'End If
ndr.EndEdit()
dt.Rows.Add(ndr)

dgv.Rows(dgv.Rows.Count
- 1).DefaultCellStyle.BackColor = Color.FromArgb(255, 255, 210)
dgv.Rows(dgv.Rows.Count
- 1).DefaultCellStyle.Font = font
dgv.Rows(dgv.Rows.Count
- 1).[ReadOnly] = True

If dgv.Tag Is Nothing Then
For Each dgvc As DataGridViewColumn In dgv.Columns
dgvc.SortMode
= DataGridViewColumnSortMode.Programmatic
Next
End If
dgv.Tag
= ndr
End Sub
Private Sub dataGridView_ColumnHeaderMouseClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs)
Dim sortDgv As DataGridView = DirectCast(sender, DataGridView)
Dim font As New Font(dgv.ColumnHeadersDefaultCellStyle.Font.FontFamily, dgv.ColumnHeadersDefaultCellStyle.Font.Size, FontStyle.Bold)
Dim fx As Integer = 0
If sortDgv.AccessibleDescription Is Nothing Then
fx
= 1
Else
fx
= Integer.Parse(sortDgv.AccessibleDescription)
fx
= (If(fx = 0, 1, 0))
End If
sortDgv.AccessibleDescription
= fx.ToString()
'If sortDgv.Columns(e.ColumnIndex).Name = "@xu.Hao" Then
' Exit Sub
'End If
Dim nCol As DataGridViewColumn = sortDgv.Columns(e.ColumnIndex)

If nCol.DataPropertyName = String.Empty Then
Exit Sub
End If

If nCol IsNot Nothing Then

sortDgv.Sort(nCol,
If(fx = 0, ListSortDirection.Ascending, ListSortDirection.Descending))
End If
'--
Dim dr As DataRow = DirectCast(sortDgv.Tag, DataRow)
Dim dt As DataTable = DirectCast(sortDgv.DataSource, DataTable)
Dim ndr As DataRow = dt.NewRow()
ndr.BeginEdit()
For i As Integer = 0 To dt.Columns.Count - 1
ndr(i)
= dr(i)
Next
dt.Rows.Remove(dr)


'if (e.ColumnIndex != 0)
If True Then
Dim n As Integer = 1
For i As Integer = 0 To sortDgv.Rows.Count - 1
Dim dgRow As DataGridViewRow = sortDgv.Rows(i)
Dim drv As DataRowView = DirectCast(dgRow.DataBoundItem, DataRowView)
Dim tdr As DataRow = drv.Row
tdr.BeginEdit()
tdr(
"@xu.Hao") = n
n
+= 1

tdr.EndEdit()
Next
sortDgv.Refresh()
sortDgv.RefreshEdit()

End If
ndr(
"@xu.Hao") = CInt((dt.Rows.Count + 1)).ToString()
ndr.EndEdit()
dt.Rows.Add(ndr)
sortDgv.Tag
= ndr

'--
sortDgv.Sort(sortDgv.Columns("@xu.Hao"), ListSortDirection.Ascending)
sortDgv.Columns(
"@xu.Hao").HeaderCell.SortGlyphDirection = SortOrder.None
nCol.HeaderCell.SortGlyphDirection
= If(fx = 0, SortOrder.Ascending, SortOrder.Descending)

sortDgv.Rows(sortDgv.Rows.Count
- 1).DefaultCellStyle.BackColor = Color.FromArgb(255, 255, 210)
sortDgv.Rows(sortDgv.Rows.Count
- 1).DefaultCellStyle.Font = Font
End Sub
Private Sub dataGridView_DataSourceChanged(ByVal sender As Object, ByVal e As EventArgs)
Dim dgv As DataGridView = DirectCast(sender, DataGridView)
'DataTable dt = (DataTable)dgv.DataSource;
If dt Is Nothing Then
Exit Sub
End If
Dim tal As Decimal() = New Decimal(dt.Columns.Count - 1) {}
If dt.Columns.IndexOf("@xu.Hao") < 0 Then
Dim dc As New DataColumn("@xu.Hao", System.Type.[GetType]("System.Int32"))
dt.Columns.Add(dc)
dgv.Columns(
"@xu.Hao").DisplayIndex = 0
dgv.Columns(
"@xu.Hao").HeaderText = "序号"

dgv.Columns(
"@xu.Hao").SortMode = DataGridViewColumnSortMode.Programmatic
dgv.AutoResizeColumn(dgv.Columns(
"@xu.Hao").Index)

dgv.Columns(
"@xu.Hao").DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter
dgv.Columns(
"@xu.Hao").Visible = False
End If
SumDataGridView(dgv, sc)
End Sub
Private Sub dataGridView_CellValueChanged(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)

Dim dgv As DataGridView = DirectCast(sender, DataGridView)
If dgv.Tag Is Nothing OrElse e.RowIndex < 0 OrElse e.RowIndex = dgv.Rows.Count - 1 Then
Exit Sub
End If

Dim col As String = dgv.Columns(e.ColumnIndex).DataPropertyName
If col = String.Empty Then
Exit Sub
End If
If DirectCast(dgv.Rows(e.RowIndex).DataBoundItem, DataRowView).Row.Table.Columns(col).DataType.IsValueType Then
Dim tal As Decimal = 0
For Each dgvr As DataGridViewRow In dgv.Rows
If dgvr.Index <> dgv.Rows.Count - 1 Then
Dim hej As String = dgvr.Cells(e.ColumnIndex).Value.ToString()
If hej <> String.Empty Then
tal
+= Decimal.Parse(hej)
End If
End If
Next
If tal = 0 Then
dgv(e.ColumnIndex, dgv.Rows.Count
- 1).Value = DBNull.Value
Else
dgv(e.ColumnIndex, dgv.Rows.Count
- 1).Value = tal
End If
End If
End Sub

Private Sub dataGridView_RowPostPaint(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewRowPostPaintEventArgs)
Dim dgv As DataGridView = DirectCast(sender, DataGridView)

Dim font As New Font(dgv.ColumnHeadersDefaultCellStyle.Font.FontFamily, dgv.ColumnHeadersDefaultCellStyle.Font.Size, FontStyle.Bold)
Dim rectangle As Rectangle = New Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, dgv.RowHeadersWidth - 4, e.RowBounds.Height)
If e.RowIndex = dgv.Rows.Count - 1 Then
TextRenderer.DrawText(e.Graphics,
"合计", font, rectangle, dgv.ColumnHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter Or TextFormatFlags.Right)
Else
TextRenderer.DrawText(e.Graphics, (e.RowIndex
+ 1).ToString(), dgv.RowHeadersDefaultCellStyle.Font, rectangle, dgv.RowHeadersDefaultCellStyle.ForeColor, TextFormatFlags.VerticalCenter Or TextFormatFlags.Right)
End If


End Sub
End Class
End Namespace


在DataGridView的窗体中:

'...
Imports getdywsd.OtherTools
'
da.Fill(dt)
        
Dim scol As String() = New String() {"销售数量""码洋""实洋"}  '制定哪些列需要汇总
        
Dim ot As New DataGridViewAddSumRow
        ot.SortColsName 
= scol
        ot.dataTableName 
= dt
        ot.DgvName 
= DataGridView1
        ot.begin()
'
posted @ 2009-09-17 15:40  Tuwi  阅读(7771)  评论(2编辑  收藏  举报