2012-02-13 99 views
2

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

(DataTable)UltraGrid1.DataSource 

但问题是,在这个新的DataTable列的顺序是不可见的序列用户设置... 我怎样才能改变UltraWinGrid的DataSource到我可以在屏幕上的Grid中看到的现在?

+0

为什么订单需要在DataTable中的一样吗?无论DataTable中的顺序如何,WinGrid应该仍然能够以正确的顺序显示数据?如果您发现情况并非如此,那么您的列键可能不匹配,因此网格可能会创建新的乐队和列。您可以使用NewBandLoadStyle和/或NewColumnLoadStyle关闭DisplayLayout设置为false来确认这一点。我建议您验证DataTable中的列名称与网格中列的键是否匹配。 – alhalama 2012-02-13 13:30:09

+0

@ alhalama,谢谢你的答复。但我想我无法正确描述我的问题。我的应用程序用户可以修改WinGrid(例如选择他想在网格中看到的列,并且也改变它们的顺序),然​​后当他按下“打印”按钮,当前列和序列和数据的当前WinGrid应该作为DataTable类型中的参数发送到类。现在我该怎么办? – 2012-02-14 05:08:48

+0

请帮我... – 2012-02-14 08:11:43

回答

0

WinGrid 数据源包含与显示网格时属性相同的对象。
如果您的用户通过WinGrid界面更改了列的顺序或可见性,则底层数据源完全不受影响。
我想到的唯一解决方案(对于大型表非常昂贵)是使用DataTable Copy()方法来获取不同的表格,然后通过grid.DisplayLayout.Band [0] .Columns并使用复制的DataTable 删除()方法为隐藏在网格上的列(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++); 
} 
+0

只是为了检查OP。你解决了你的任务吗? – Steve 2012-02-29 17:05:12

0

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