我们使用C1Flexgrid的DataMap属性在列设置单元格的值和展示值相关联, 并排序,这个时候的排序,是基于实际的值,例如:关键值。
有些客户需要基于展示值对列进行排序,本文就介绍如何实现这个需求。
首先,我们需要绑定C1Flexgrid到数据源。
保存Northwind数据源的Products数据表,然后创建两个Dictionary对象,可以设置SupplierID列和CategoryID 列的DataMap属性。
下面代码展示CompanyName替代SupplierID和CategoryName替代CategoryID。
// load data into some tables var dtProducts = GetDataTable("Products"); var dtCategories = GetDataTable("Categories"); var dtSuppliers = GetDataTable("Suppliers"); // create two data maps var mapCat = new Dictionary(); foreach (DataRow row in dtCategories.Rows) { var key = (int)row["CategoryID"]; var val = (string)row["CategoryName"]; mapCat[key] = val; } var mapSup = new Dictionary (); foreach (DataRow row in dtSuppliers.Rows) { var key = (int)row["SupplierID"]; var val = (string)row["CompanyName"]; mapSup[key] = val; } // bind grid _flex.DataSource = dtProducts; // add data maps _flex.Cols["CategoryID"].DataMap = mapCat; _flex.Cols["SupplierID"].DataMap = mapSup;
如果运行上述代码尝试对CategoryID/SupplierID列排序,它们会由关键值排序。
接着,添加如下的代码进行处理。
主要处理BeforeSort事件,添加新列到数据表。新列是隐藏的,由mapped值添充。表格会基于新列排序,而不是单击的列。这样就会根据展示的值排序而不是关键值。
代码如下:
// name of the hidden column used to perform the actual sorting const string SORT_COL_NAME = "_dtSort"; // column being used as a source for the hidden source column C1.Win.C1FlexGrid.Column _sourceColumn; // apply custom sort (use mapped values instead of raw) void _flex_BeforeSort(object sender, C1.Win.C1FlexGrid.SortColEventArgs e) { // if the column contains a data map _sourceColumn = _flex.Cols[e.Col]; if (_sourceColumn.DataMap != null) { // add a hidden column just for sorting var dt = _flex.DataSource as DataTable; if (!dt.Columns.Contains(SORT_COL_NAME)) { var dcol = dt.Columns.Add(SORT_COL_NAME); _flex.Cols[SORT_COL_NAME].Visible = false; } // remove current sort (if any) dt.DefaultView.Sort = string.Empty; // populate the sort column foreach (DataRow dr in dt.Rows) { var key = dr[_sourceColumn.Name]; dr[SORT_COL_NAME] = _sourceColumn.DataMap[key]; } // apply the new sort var sort = SORT_COL_NAME; if ((e.Order & C1.Win.C1FlexGrid.SortFlags.Descending) != 0) { sort += " DESC"; } dt.DefaultView.Sort = sort; // handled e.Handled = true; } }
遗留下来的问题就是处理AfterEdit 事件,更新隐藏排序列的内容。当用户编辑列包含data map,自动更新排序。
如下代码:
// update sort when the user edits the sorted column void _flex_AfterEdit(object sender, C1.Win.C1FlexGrid.RowColEventArgs e) { // if the user edited the column being sorted on if (_flex.Cols[e.Col] == _sourceColumn) { // refresh the content of the sort column var dt = _flex.DataSource as DataTable; foreach (DataRow dr in dt.Rows) { var key = dr[_sourceColumn.Name]; dr[SORT_COL_NAME] = _sourceColumn.DataMap[key]; } } }
完整的代码实现在附件里,请参考:
如果你对ComponentOne感兴趣,请到我们的官网下载最新版本:/download/?pid=3
如果你有疑问,可以到GCDN论坛获得技术支持:http://gcdn.grapecity.com.cn/showforum-68.html