我的表单中有一个UltraWinGrid,用户允许更改它的列序列。我在表单中有一个按钮,它应该将此Grid的DataSource作为DataTable发送到生成报告的类。 我使用以下代码将DataSource强制转换为DataTable:
(DataTable)UltraGrid1.DataSource
但问题是这个新DataTable中的列序列不是用户设置的可见序列... 如何将UltraWinGrid的DataSource更改为我现在可以在屏幕上看到的?
答案 0 :(得分:0)
您可以遍历列,然后使用Header.VisiblePosition属性来确定列的顺序。确定订单后,您需要在DataTable中设置适当的订单。
答案 1 :(得分:0)
WinGrid 数据源包含显示网格时分配给属性的同一对象。
如果您的用户通过WinGrid界面更改列的顺序或可见性,则基础数据源不会受到影响在我看来,唯一的解决方案(对于大型表来说非常昂贵)是DataTable Copy()方法来获取要处理的不同表,然后循环遍历 grid.DisplayLayout.Band [0] .Columns 并对网格上隐藏的列(Column.Hidden)使用复制的DataTable Remove()方法。
棘手的部分是列的顺序。
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++);
}