WinForm中DATAGRID排序问题,允许排序导致通过当前行的索引获得的行不是界面上看到的那个行,哪位大哥帮忙解决一下,谢谢! 有时候打不开http://www.syncfusion.com/FAQ/WinForms/FAQ_c44c.asp 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 BindingManagerBase bm = this.dataGrid1.BindingContextr[this.dataGrid1.DataSource, this.dataGrid1.DataMember]; DataRow dr = ((DataRowView)bm.Current).Row; 找到一个这样的方法,有没有更好的? 真是蛮麻烦得一件事情,我得解决办法时:在Datagrid1_MouseDown中对DataSet的数据重新读取,按照新的排序方式,再绑定到dataGrid,代码大致如下,你可以参考一下:private void dataGrid1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e){ DataGrid myGrid = (DataGrid) sender; System.Windows.Forms.DataGrid.HitTestInfo hti; hti = myGrid.HitTest(e.X, e.Y); if(hti.Type==System.Windows.Forms.DataGrid.HitTestType.ColumnHeader) { for(int j=0;j<sFieldSort.Length;j++) { if(j!=hti.Column)sFieldSort[j]=""; } if(sFieldSort[hti.Column]=="")sFieldSort[hti.Column]="asc"; else if(sFieldSort[hti.Column]=="asc")sFieldSort[hti.Column]="desc"; else if(sFieldSort[hti.Column]=="desc") sFieldSort[hti.Column]="asc"; sOrder=" order by "+myGrid.TableStyles[0].GridColumnStyles[hti.Column].MappingName + " "+sFieldSort[hti.Column]; if(myGrid.TableStyles[0].GridColumnStyles[hti.Column].MappingName!="JCODE") sOrder+=",JCODE asc"; SetDataGrid(5); }}private void SetDataGrid(int iRefreshType){ int iCurrentRowIndex=dataGrid1.CurrentRowIndex; if(iRefreshType != 4)//cancel的情况无须更新记录集 { if(dsJCODE!=null) { if(dsJCODE.Tables.Count >0) dsJCODE.Tables.Clear(); } dsJCODE=Stub.GetInstance().GetDataSet("select * from JCODE "+sOrder,"JCODE"); if(iRefreshType != 5)dataGrid1.DataSource=dsJCODE.Tables[0]; dataGrid1.Refresh(); } //重设当前的行索引 SysDataGrid.SetDataGridCurrentRowIndex(dataGrid1,dsJCODE.Tables[0],iRefreshType,iCurrentRowIndex,"JCODE",this.txtJCODE.Text.Trim()); if((dataGrid1.CurrentRowIndex == 0 && iRefreshType != 1 && iRefreshType != 2 ) || iRefreshType == 4) this.DisPlayValue();//重新显示数据} 我还没去试,大概可以用,可是这样会不会太复杂了点,我的想法是可不可以在从数据库里面取出来的DATASET和DATAGRID.DATASOURCE之间做一些处理,那原来的通过取当前行索引获取的记录不变?为什么这样想呢,主要是因为我这个项目原先没有排序,所以很多地方都是这样用的,可是现在的新需求要求要排序,结果就出现这个问题了,所以我希望找到一种工作量最少的解决方法。 我以前也遇到这样的问题,我记得当时我用了一个方法,就是使用DataGrid的位置信息进行数据读取和操作,不过用位置信息做的话,有一个不好之处就是你要对数据结构记得非常清,读入的,原始的,否则你就要总是去查,不过据一些专家说,用位置信息速度快,可读性差点。具体方法是用DataGrid[x,y]在MSDN的例子上有这样用的,你可以去查一下。 补充说明,用我的代码,那项目中只要牵涉到用类似于p_dt.Rows[this.dgSOList.CurrentRowIndex]["ORDERSTATUS"]的代码都要改,项目中很多地方使用该代码 DataRowView drv = (DataRowView)this.BindingContext[ds,"table"].Current;drv.Row就是DataSet中的当前行了,是吧? BindingManager bm = (BindingManager)this.dataGrid1.BindingContext[this.dataGrid1.DataSource]; DataRow dr = (DataRowView)bm.Current比较好了。 最好将DataGrid绑定到DataView上,而不是DataSet或者DataTable上例如:DataGrid grd;DataTable table;......DataView view = new DataView(table);grd.DataSource = view;......// 取值的时候就从DataView中取值DataRow row = view [grd.SelectIndex].Row; 我晕啊,我是专门今天来看你这种问题的!!!我也一样啊,对view排列后,里面的index号就不再是dataSet中的行号了!!!很明显的排序后的列都是从0开始!!!所以每次排序后同一行可能就不是同一index !!!!!我在郁闷中也想解决。。我不能得到当前用户选择的行数据了!!因为行号根本就不一样了。怎么办。。高手请教谢谢了。帮你顶楼主!!! 我总结我以上方法:==========1楼方的方法=======BindingManagerBase bm = this.dataGrid1.BindingContextr[this.dataGrid1.DataSource, this.dataGrid1.DataMember]; DataRow dr = ((DataRowView)bm.Current).Row; =================新方法1====DataRowView drv = (DataRowView)this.BindingContext[ds,"table"].crrent; drv.row=================新方法2====用DataGrid[x,y]=================新方法3====将DataGrid绑定到DataView上,而不是DataSet或者DataTable上取值的时候就从DataView中取值DataRow row = view [grd.SelectIndex].Row;=============================这些方法都可以解决由于索引而引起的Grid内的行索引与DataSet不相同,只是这些方法没有一种可以解决楼主的话题,我也是想,如果你的p_dt.Rows[this.dgSOList.CurrentRowIndex]["ORDERSTATUS"]这种代码不改是不行的了,因为排序后,CureentRowIndex得到的只是grid的一个索引,根本不与DataSet里的索引相同了,只有没有经过排序的Grid才能这样写!楼主改代码吧!程序员是不能不写代码的,呵呵 楼主,这样还可以得到选择行的Position,就是在DataSet中的真正行号指针。BindingManagerBase bmb=dataGrid.BindingContext[dataGrid.DataSource,dataGrid.dataMember];int position=bmb.Position; 我知道,我最后也是用这种方法实现的,但是这样还是牵涉到改所有用到类似p_dt.Rows[this.dgSOList.CurrentRowIndex]["ORDERSTATUS"]的代码。我发出这个贴只是想找到有没有优于它的解决方法 我昨天晚上,试了一下上面几种方法,晕,总的来说思路是一样的!!!我仔细的分析了下,三种方法结果得到的行都是DataGrid内选择的行!!当然也是DataGrid数据源的行,为什么是数据源的行?是因为他是DataGrid数据源,而DataGrid只是数据源的介面显示!!由此我得到以下结论:1,用以上方法只能行到当前DataGrid和DataGrid的数据行,如果DataGrid的数据源是DataSet, 那DataGrid选择的行与DataSet内当前行一样;但是,如果DataGrid的数据是DataView,而且D DataView排序后,那DataGrid当前行只与它的数据对应,也就是DataView对应, 要注意的是这时,排序后DataGrid当前行与DataSET当前行不一样!!!!只与DataView一样!2,如果DataGrid数据源用DataView,那不管怎样排序,DataGrid行与当前DataView行是一样的。3,如果DataGrid数据源用DataSet内的表,那DataGrid当前行与DataSet对应的表也是对应的, 也就是说,DataGrid当前行也是DataSet内的当前行。4,如果情况如果3,在DataSet对Sql参数进行动态改变,如果Where 条件的变动,这时DataSet内的数据 应改变了,如果DataGrid同时刷新的话,我也DataGrid与DataSet当前行也是对应的, 不过,这一条我还没有证实,正常来说应如此。 楼主,经过这一贴,我对Ado算是有个初步认识了,我刚学.net,呵呵,以前用Delphi,好象很多思路是一样的。 不好意思是,我还没有找到方法,可以不必代码也,解决楼主的问题。真是惭愧!再次:to ....... ms44(ms44)我想你前年碰到的问题,看了这个贴应当可以解决了!! 虽然没能找到更好的方法,但谢谢大家的积极参与,特别是guishuanglin(小桂子) 。再放下去大概也不会有什么好的,所以决定现在结贴了。 js单线程异步 fileNotFoundException错误。 怎么我定义operator ==后,使用一直报错? js文件中调用Ajax方法 VS2008【从元数据】的问题 关于写入文本文件问题 关于权限设置的问题 如保获取DATAGRID当前格的座标? 怎样把从数据表里面取出的数据,在c#中付给textbox 怎样显示一条横线,就是在一些windows的窗体上,确定取消按扭上面的那条线 求True DBGrid for .Net控件及注册码 蚕蛹、米花、woodlet (木头)等短信高手请进,西门子3508的问题?
DataRow dr = ((DataRowView)bm.Current).Row;
找到一个这样的方法,有没有更好的?
在Datagrid1_MouseDown中对DataSet的数据重新读取,按照新的排序方式,再绑定到dataGrid,代码大致如下,你可以参考一下:
private void dataGrid1_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
{
DataGrid myGrid = (DataGrid) sender;
System.Windows.Forms.DataGrid.HitTestInfo hti;
hti = myGrid.HitTest(e.X, e.Y);
if(hti.Type==System.Windows.Forms.DataGrid.HitTestType.ColumnHeader)
{
for(int j=0;j<sFieldSort.Length;j++)
{
if(j!=hti.Column)sFieldSort[j]="";
}
if(sFieldSort[hti.Column]=="")sFieldSort[hti.Column]="asc";
else if(sFieldSort[hti.Column]=="asc")sFieldSort[hti.Column]="desc";
else if(sFieldSort[hti.Column]=="desc") sFieldSort[hti.Column]="asc";
sOrder=" order by "+myGrid.TableStyles[0].GridColumnStyles[hti.Column].MappingName + " "+sFieldSort[hti.Column];
if(myGrid.TableStyles[0].GridColumnStyles[hti.Column].MappingName!="JCODE")
sOrder+=",JCODE asc";
SetDataGrid(5);
}
}private void SetDataGrid(int iRefreshType)
{
int iCurrentRowIndex=dataGrid1.CurrentRowIndex;
if(iRefreshType != 4)//cancel的情况无须更新记录集
{
if(dsJCODE!=null)
{
if(dsJCODE.Tables.Count >0)
dsJCODE.Tables.Clear();
}
dsJCODE=Stub.GetInstance().GetDataSet("select * from JCODE "+sOrder,"JCODE");
if(iRefreshType != 5)dataGrid1.DataSource=dsJCODE.Tables[0];
dataGrid1.Refresh();
} //重设当前的行索引
SysDataGrid.SetDataGridCurrentRowIndex(dataGrid1,dsJCODE.Tables[0],iRefreshType,iCurrentRowIndex,"JCODE",this.txtJCODE.Text.Trim()); if((dataGrid1.CurrentRowIndex == 0 && iRefreshType != 1 && iRefreshType != 2 ) || iRefreshType == 4)
this.DisPlayValue();//重新显示数据
}
drv.Row就是DataSet中的当前行了,是吧?
DataRow dr = (DataRowView)bm.Current
比较好了。
例如:
DataGrid grd;
DataTable table;
...
...
DataView view = new DataView(table);
grd.DataSource = view;
...
...
// 取值的时候就从DataView中取值
DataRow row = view [grd.SelectIndex].Row;
我也一样啊,对view排列后,里面的index号就不再是dataSet中的行号了!!!很明显的
排序后的列都是从0开始!!!所以每次排序后同一行可能就不是同一index !!!!!
我在郁闷中也想解决。。
我不能得到当前用户选择的行数据了!!因为行号根本就不一样了。
怎么办。。高手请教
谢谢了。
帮你顶楼主!!!
==========1楼方的方法=======
BindingManagerBase bm = this.dataGrid1.BindingContextr[this.dataGrid1.DataSource, this.dataGrid1.DataMember];
DataRow dr = ((DataRowView)bm.Current).Row;
=================新方法1====
DataRowView drv = (DataRowView)this.BindingContext[ds,"table"].crrent;
drv.row
=================新方法2====
用DataGrid[x,y]
=================新方法3====
将DataGrid绑定到DataView上,而不是DataSet或者DataTable上
取值的时候就从DataView中取值
DataRow row = view [grd.SelectIndex].Row;
=============================
这些方法都可以解决由于索引而引起的Grid内的行索引与DataSet不相同,
只是这些方法没有一种可以解决楼主的话题,
我也是想,如果你的
p_dt.Rows[this.dgSOList.CurrentRowIndex]["ORDERSTATUS"]
这种代码不改是不行的了,因为排序后,CureentRowIndex得到的只是grid的一个索引,根本不与
DataSet里的索引相同了,
只有没有经过排序的Grid才能这样写!
楼主改代码吧!程序员是不能不写代码的,呵呵
就是在DataSet中的真正行号指针。
BindingManagerBase bmb=dataGrid.BindingContext[dataGrid.DataSource,dataGrid.dataMember];
int position=bmb.Position;
的代码。我发出这个贴只是想找到有没有优于它的解决方法
晕,总的来说思路是一样的!!!我仔细的分析了下,
三种方法结果得到的行都是DataGrid内选择的行!!当然也是DataGrid数据源的行,
为什么是数据源的行?是因为他是DataGrid数据源,而DataGrid只是数据源的介面显示!!
由此我得到以下结论:
1,用以上方法只能行到当前DataGrid和DataGrid的数据行,如果DataGrid的数据源是DataSet,
那DataGrid选择的行与DataSet内当前行一样;但是,如果DataGrid的数据是DataView,而且D
DataView排序后,那DataGrid当前行只与它的数据对应,也就是DataView对应,
要注意的是这时,排序后DataGrid当前行与DataSET当前行不一样!!!!只与DataView一样!
2,如果DataGrid数据源用DataView,那不管怎样排序,DataGrid行与当前DataView行是一样的。
3,如果DataGrid数据源用DataSet内的表,那DataGrid当前行与DataSet对应的表也是对应的,
也就是说,DataGrid当前行也是DataSet内的当前行。
4,如果情况如果3,在DataSet对Sql参数进行动态改变,如果Where 条件的变动,这时DataSet内的数据
应改变了,如果DataGrid同时刷新的话,我也DataGrid与DataSet当前行也是对应的,
不过,这一条我还没有证实,正常来说应如此。
我刚学.net,呵呵,以前用Delphi,好象很多思路是一样的。
真是惭愧!再次:to ....... ms44(ms44)
我想你前年碰到的问题,看了这个贴应当可以解决了!!