找回密码
 立即注册

QQ登录

只需一步,快速开始

yin_tb

中级会员

53

主题

198

帖子

993

积分

中级会员

积分
993

微信认证勋章

yin_tb
中级会员   /  发表于:2021-5-17 18:57  /   查看:4696  /  回复:16
1金币
如题,马工,原来请教过你这个问题,我以前的问题贴子里有,你也回复了我解决办法,即:加了一个标识isentered = True。具体不说了。我在我的程序里,底层封装了TrueDBgrid,加了很多功能,一直以来,回车换行我没来得急弄,今天改底层,把最后一个单元格时回车换行加上,我发现你给我的解决办法只能完成正常状态的情况,意思如下:

如果网格里有 citem_no,citem_name,nqty,nprice,namount,cmemo这些列,
1、都显示,可以,那么用 //但是,运行时也不能拖动列调位置
if (col==tgrid1.Columns.Count-1) //当前是最后一列
{
if (row==tgrid1.VisbleRows-1 //最后一行,必须用这个,绑定状态下不能用RowCount,系统会报错,本身系统也提示说了那是非绑定用的。
{
}
}
2、但是,如果网格中的列是根据存在数据库中显示与否标识动态加载的话,比如上面这些,只显示citem_no,citem_name,nqty 此时,程序执行的逻辑就不对了,或者根本不跳到下一行,核心问题还是,Col属性与Columns.Count没有可比性,此时,col的值应该是2,通过测试,我始终发现,Col是创建列时的定死的值,甚至你在运行起来程序,拖动列调了位置,Col属性是不变的。我也用VisbleCols属性试了,代表显示了多少列,Col与它也没有可比性。

马工,我上面说的对吗?
>>>>>所以,基于以上原因,我继承重写了C1DataColumn为一个新对象,给它加了一个像微软的DataGridView中的列的index一样的属性,给主网格加了一个int_count属性,在动态创建列时,每建一个列,当是显示的, int_count加1,并且赋值index属性等于int_count,这样,在KEYdown事件里,我比对列的index是否等于int_count。这种方法临时实现了需求,但若用户在运行时,拖动调整列的位置,还是不行。因为,C1TrueDBgrid不像微软的DataGridView一样,列有个DisplayIndex属性,拖动时是实时变的。若要从根本上解决,看来,也得弄个DisplayIndex属性,并且在列的位置调整时,更新这个属性。
马工,我说的是否正确?还是说不正确,把简单问题复杂化了?
如果正确,也希望别人遇到此问题,有些帮助。

最佳答案

查看完整内容

之前的代码确实有点问题 c1TrueDBGrid1.Col获取到的是当前选中单元格所在的displaycolumn列表中的索引值(和实际显示的顺序相关,但是和是否隐藏无关), 对你这边代码中的判断方式稍微进行了修改,请参考以下代码

16 个回复

倒序浏览
最佳答案
最佳答案
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-5-17 18:57:21
来自 15#
之前的代码确实有点问题
c1TrueDBGrid1.Col获取到的是当前选中单元格所在的displaycolumn列表中的索引值(和实际显示的顺序相关,但是和是否隐藏无关),

对你这边代码中的判断方式稍微进行了修改,请参考以下代码
  1.         private void tgrid1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
  2.         {
  3.             //回车跳转
  4.             if (tgrid1.VisibleRows ==0)
  5.             { return; }
  6.             var lastDisplayColumn = tgrid1.Splits[0].DisplayColumns.Cast<C1DisplayColumn>().Where(t => t.Visible).Last();
  7.             var selectedColumn = tgrid1.Splits[0].DisplayColumns[tgrid1.Col];
  8.             tgrid1.DirectionAfterEnter = DirectionAfterEnterEnum.MoveRight;
  9.            if (selectedColumn==lastDisplayColumn)
  10.                 {
  11.                 tgrid1.DirectionAfterEnter = DirectionAfterEnterEnum.MoveNone;
  12.                 if (tgrid1.Row==tgrid1.VisibleRows -1)
  13.                     { return; }
  14.                 else
  15.                 {
  16.                     tgrid1.Row = tgrid1.Row + 1;
  17.                     tgrid1.Col = 0;
  18.                  }
  19.             }
  20.         }
复制代码
回复 使用道具 举报
yin_tb
中级会员   /  发表于:2021-5-18 06:18:30
2#
本帖最后由 yin_tb 于 2021-5-18 07:01 编辑

在昨天代码的基础上,做了测试,发现有时(只是有时候),即使拖动了位置,最后一个单元格时,回车也能自动换行,但有时不行,
通过跟踪发现,不行的时候,在最后一个单元格,按回车时,我的最后一列的index值为0了,因为我是用DirectCast(Columns(col),MyColumn).index来获取的。
在底层,我继承TrueDBgrid写了个新对象MyVouchGrid,同时,MyColumn是继承C1DataCoumn写的,然后在MyVouchGrid的KeyDown事件里实现回车换行。

重点:1、通过测试发现,当不能自动换行时,焦点在最后一个单元格,回车,焦点还在那,但获取index的值发现,是0。
2、能自动换行时,如果最后一列的index是7,系统自动跳到了下一行的第二个单元格,index属性不是1(C1TrueDBgrid的col是从0开始的),是8。当再按一次回车,index是2了。
也就是说,每次回车,它MoveRight了一次。C1TrueDBgrid已经改变了col属性,只能这样理解。

晕,有点找不到东南西北了。为了目的,用ColMove事件来重置所有列的index属性,每当用户拖动列时,用 VisbleCols的数量来循环重置所有列的index,这样应该可以。

回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-5-18 11:07:12
3#
问题已经收到,我先在我这里测试验证看看
回复 使用道具 举报
yin_tb
中级会员   /  发表于:2021-5-18 11:14:47
4#
本帖最后由 yin_tb 于 2021-5-18 11:17 编辑

你也不用像我一样,从数据库查询格式,动态加载。你直接在TrueDBgrid的设计器里,定义5-6个列,然后,运行起来,在代码里隐藏最后的列或哪些列,并且随意拖动列到新位置,你看回车还会换行吧。为了演示,你还是得赋值几行数据,非绑定datatable或建个datatable,初始几行数据
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-5-18 15:09:53
5#
针对你这边的问题,你可以测试下以下代码,放在PreviewKeyDown事件中,

由于c1TrueDBGrid1.Col本身获取到的就是实际显示的列号,因此不会受到隐藏列或者调整列顺序的影响,始终还是以显示的最后一列来判断



  1.         private void c1TrueDBGrid1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
  2.         {

  3.             c1TrueDBGrid1.DirectionAfterEnter = C1.Win.C1TrueDBGrid.DirectionAfterEnterEnum.MoveRight;
  4.             if (c1TrueDBGrid1.Col == c1TrueDBGrid1.Splits[0].DisplayColumns.Count - 1)
  5.             {
  6.                 c1TrueDBGrid1.DirectionAfterEnter = C1.Win.C1TrueDBGrid.DirectionAfterEnterEnum.MoveNone;
  7.                 c1TrueDBGrid1.Row = c1TrueDBGrid1.Row + 1;
  8.                 c1TrueDBGrid1.Col = 1;
  9.             }

  10.         }
复制代码
回复 使用道具 举报
yin_tb
中级会员   /  发表于:2021-5-18 15:38:29
6#
本帖最后由 yin_tb 于 2021-5-18 15:40 编辑

我试了你说的方法,虽然PreviewKeyDown事件的思路不错,不过,不行,还是我说的意思,比如有6列,citem_no,citem_name,nqty,nprice,namount,cmemo,cmemo的col是5对吧,你把它隐藏掉,到最后一个单元格namount时,回车,是不换行的,因为namount的col是4,但c1TrueDBGrid1.Splits[0].DisplayColumns.Count - 1是5,没有可比性。咱们通话,你可能还没明白我说的,col属性,在定创建了列,它就不变了,你拖动列,调位置,它是不变的,如上面6个列,citem_name的col是1,就算你把它拖到cmemo后面,它还是1
回复 使用道具 举报
yin_tb
中级会员   /  发表于:2021-5-18 15:45:53
7#
我又发现我说的也不对,我跟踪了一下,COL是变的,真晕了,呵呵。我再试试
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-5-18 15:54:22
8#
对代码进行了一点修改,通过
  1. var visiableColCount = c1TrueDBGrid1.Splits[0].DisplayColumns.Cast<C1DisplayColumn>().Where(t => t.Visible).Count();
复制代码

可用获取到可见行的数量,

另外下面附了一个隐藏最后一列的方法,也是类似的思路,已测试列隐藏后也是没有问题的

  1.         private void c1TrueDBGrid1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
  2.         {
  3.             var visiableColCount = c1TrueDBGrid1.Splits[0].DisplayColumns.Cast<C1DisplayColumn>().Where(t => t.Visible).Count();
  4.             c1TrueDBGrid1.DirectionAfterEnter = C1.Win.C1TrueDBGrid.DirectionAfterEnterEnum.MoveRight;
  5.             if (c1TrueDBGrid1.Col == visiableColCount - 1)
  6.             {
  7.                 c1TrueDBGrid1.DirectionAfterEnter = C1.Win.C1TrueDBGrid.DirectionAfterEnterEnum.MoveNone;
  8.                 c1TrueDBGrid1.Row = c1TrueDBGrid1.Row + 1;
  9.                 c1TrueDBGrid1.Col = 1;
  10.             }

  11.         }

  12.         private void 隐藏最后一列ToolStripMenuItem_Click(object sender, EventArgs e)
  13.         {
  14.             c1TrueDBGrid1.Splits[0].DisplayColumns.Cast<C1DisplayColumn>().Where(t => t.Visible == true).Last().Visible=false;
  15.         }
复制代码
回复 使用道具 举报
yin_tb
中级会员   /  发表于:2021-5-18 15:59:31
9#
我用你的方法试试,感觉好像对,呵呵
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部