要如何讓 DataGrid 中的流水號欄位依排序的順序走(Always 1, 2, 3 ...)
如何知道 DataGrid 何時排序完成呢?
可以在 DataGrid 排序後,做某些事嗎?
環境
.NET 1.1, Windows Form, VB.NET
問題
要在 DataGrid Sort 後,修改原本流水號(例如:c1)的值,讓它依排序的流水號走(Always 1, 2, 3....)
目前 DataGrid 的流水號欄位,會因為依其他欄位排序,同時流水號會不同,如下,
客戶想要的是 DataGrid 的流水號欄位 Always 是 1, 2, 3 ….. 如下,
已知條件
DataGrid 的 DataSource 為 DataTable
研究及實作
本來想找看看DataGrid之中是否有排序的事件可以處理,後來參考到「Sorting DataGrid programmatically」。
在 DataGrid 的 Header 中按下 Click 排序時,會 Trigger Data的 ListChanged 事件。
所以可以在 Data 的 DataView ListChanged 事件中來重新建立一個 DataTable,同時重新設定流水號欄位的值。
再將這個處理過的 DataTable Bind給 DataGrid。
所以在畫面上拉一個 DataGrid (DataGrid1),再拉一個 Button(btnBindData) ,在 Click 事件中模擬將查詢結果 Bind 到 DataGrid 上。
程式如下,
'要處理排序的DataGrid Private BindingGrid As DataGrid = Nothing '流水號欄位名稱 Private GridSeqNoColumnName As String = "c1" Private Sub btnBindData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBindData.Click '取得Search 的結果 Dim dtSearchResult As DataTable = GetSearchResult() 'Bind DataSource DataGrid1.DataSource = dtSearchResult '要處理的 DataGrid BindingGrid = DataGrid1 '流水號欄位名稱 GridSeqNoColumnName = "c1" '設定Grid排序後要處理的事件, 一開始沒有排序欄位 BindDataSortEvent(dtSearchResult, AddressOf OnGridSorted, String.Empty) End Sub '建立測試的資料 Private Function GetSearchResult() As DataTable Dim dtResult As New DataTable dtResult.Columns.Add("c1", GetType(Int32)) dtResult.Columns.Add("c2", GetType(String)) dtResult.Columns.Add("c3", GetType(String)) For i As Integer = 1 To 10 dtResult.Rows.Add(New Object() {i, i.ToString(), 10 * i}) Next Return dtResult End Function '設定 DataGrid 排序後,要處理的事件 Private Sub BindDataSortEvent(ByRef dt As DataTable, _ ByRef changeEvent As System.ComponentModel.ListChangedEventHandler, _ ByVal sortColumn As String) Dim list As DataView = dt.DefaultView '設定DataView的Sort欄位 list.Sort = sortColumn AddHandler list.ListChanged, changeEvent End Sub '當DataGrid排序後,要處理流水號問題 Private Sub OnGridSorted(ByVal sender As Object, _ ByVal args As System.ComponentModel.ListChangedEventArgs) Dim sortView As DataView = CType(sender, DataView) Dim orgSortColumn As String = sortView.Sort If orgSortColumn = GridSeqNoColumnName Then '在流水號的話,就不用再處理 Return End If Dim sortedData As DataTable = ReAssignDataViewSeqNoValue(sortView, GridSeqNoColumnName) BindingGrid.DataSource = sortedData '設定Grid排序後要處理的事件 BindDataSortEvent(sortedData, AddressOf OnGridSorted, orgSortColumn) End Sub '依DataView的排序,重新設定流水號的值,並回傳DataTable Private Function ReAssignDataViewSeqNoValue(ByRef dv As DataView, ByVal sewNoColumnName As String) As DataTable Dim result As DataTable = dv.Table.Clone Dim dvItems As IEnumerator = dv.GetEnumerator Dim seqNo As Integer = 0 While (dvItems.MoveNext()) seqNo += 1 Dim drv As DataRowView = dvItems.Current Dim newRow As DataRow = result.Rows.Add(drv.Row.ItemArray) newRow(sewNoColumnName) = seqNo End While Return result End Function
參考資料
Hi,
亂馬客Blog已移到了 「亂馬客 : Re:從零開始的軟體開發生活」
請大家繼續支持 ^_^