我们使用C1FlexgridDataMap属性在列设置单元格的值和展示值相关联, 并排序,这个时候的排序,是基于实际的值,例如:关键值。

有些客户需要基于展示值对列进行排序,本文就介绍如何实现这个需求。

首先,我们需要绑定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];
        }
    }
}

 

完整的代码实现在附件里,请参考:

SortDataMap.zip (11.87 kb)

 

如果你对ComponentOne感兴趣,请到我们的官网下载最新版本:/download/?pid=3

如果你有疑问,可以到GCDN论坛获得技术支持:http://gcdn.grapecity.com.cn/showforum-68.html