2

我的表单中有一个 UltraWinGrid,用户允许更改它的列顺序。我的表单中有一个按钮,它应该将此 Grid 的 DataSource 作为 DataTable 发送到生成报告的类。我使用以下代码将 DataSource 转换为 DataTable:

(DataTable)UltraGrid1.DataSource

但问题是这个新 DataTable 中的列序列不是用户设置的可见序列......我如何将 UltraWinGrid 的 DataSource 更改为我现在可以在屏幕上的 Grid 中看到的内容?

4

2 回答 2

0

您可以遍历列,然后使用 Header.VisiblePosition 属性来确定列的顺序。确定顺序后,您需要在 DataTable 中设置适当的顺序。

于 2012-02-15T05:47:10.483 回答
0

WinGrid数据源包含显示网格时分配给属性的相同对象。
如果您的用户通过 WinGrid 界面更改列的顺序或可见性,则基础数据源根本不会受到影响。
我想到的唯一解决方案(对于大表来说非常昂贵)是 DataTable Copy()方法来获取要处理的不同表,然后循环遍历grid.DisplayLayout.Band[0].Columns并使用复制的DataTable Remove()方法用于隐藏在网格上的列 (Column.Hidden)。
棘手的部分是列的顺序。
DataColumn 提供SetOrdinal更改列顺序的方法,但是,我想您需要从索引零开始向上调用此方法。因此,您需要使用Column.Header.VisiblePosition属性在网格列上进行另一个循环。
但现在还有其他问题:
首先- 必须删除 DataTable PrimaryKey,因为如果隐藏,会阻止 Remove() 方法。
其次- VisiblePosition 索引不能是连续的,如果在 SetOrdinal 中使用,则可能指向超出范围的项目。

所以让我们总结一下这个示例代码中的所有内容:(需要 Collection.Generics 和 Linq)

Dictionary<int, string> gPos = new Dictionary<int,string>();
DataTable dtCopy = (grid.DataSource as DataTable).Copy();
dtCopy.PrimaryKey = null;
foreach(UltraGridColumn gCol in grid.DisplayLayout.Bands[0].Columns)
{
    if(gCol.Hidden == true)
        dtCopy.Columns.Remove(gCol.Key);
    else
      gPos.Add(gCol.Header.VisiblePosition, gCol.Key);
}
var list = gPos.Keys.ToList();
list.Sort();
int realPos = 0;
foreach (var key in list)
{
    dtCopy.Columns[gPos[key]].SetOrdinal(realPos++);
}
于 2012-02-19T09:49:47.043 回答