外部滚动条控制DataGridView的问题,高手请进,谢谢!

九章落地 2007-12-26 10:57:54
我想通过重写DataGridView实现底部加合计行的效果,用一个VScrollBar设置FirstDisplayedScrollingRowIndex属性来控制DataGridView的垂直滚动,但当拖到底部,添加新记录时,DataGridView的最底部(默认显示背景色的一空栏)一直不能自动刷新,总会显示最后一行的列余,不能像默认的效果那样.

整整弄了一天,也没解决.快要发疯了,希望能得到您的帮助,谢谢!
下面是测试代码,Form1拖了一个DataGridView和一个VScrollBar:

private void Form1_Load(object sender, EventArgs e)
{
DataTable dt1 = new DataTable();
for (int i = 0; i < 5; i++)
{
DataColumn col = new DataColumn(i.ToString());
dt1.Columns.Add(col);
}
for (int i = 0; i < 20; i++)
{
DataRow row = dt1.NewRow();

for (int j = 0; j < 5; j++)
{
row[j] = j.ToString();
}
dt1.Rows.Add(row);
}

dataGridView1.DataSource = dt1;

vScrollBar1.Maximum = (dataGridView1.RowCount - dataGridView1.DisplayedRowCount(false) + 3) * dataGridView1.RowTemplate.Height;
vScrollBar1.Minimum = 0;
vScrollBar1.SmallChange = dataGridView1.RowTemplate.Height;
vScrollBar1.LargeChange = dataGridView1.RowTemplate.Height * 3;
}
private void vs_Scroll(object sender, ScrollEventArgs e)
{
dataGridView1.FirstDisplayedScrollingRowIndex = e.NewValue / dataGridView1.RowTemplate.Height;
Application.DoEvents();
}

private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
vScrollBar1.Maximum += dataGridView1.RowTemplate.Height;
//dataGridView1.Refresh();
}
...全文
1689 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
iloveppmm 2008-06-10
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 ydsunny 的回复:]
TO:Efcndi

我近段时间,想编一个控件,在现在的DataGridView上增加合并表头,及底部统计行.
前面我通过DataGridView里(OnPaint)重绘,功能都能做出来,如下图:


但有一个致使的缺点便是,当拖动滚动条时,有一点闪!

现在我通过组合控件的形式,用两个DataGridView+两个ScrollBar设计这样的控件,遇到了我此帖提到的怪问题...

郁闷呀!!!
[/Quote]
不知道你怎么画的,不过,我的印象中,只是在onpaint中画的话 ,应该不能用。或者说 只能看,不能碰。
iloveppmm 2008-06-10
  • 打赏
  • 举报
回复
mark
飞舞的流光 2008-05-18
  • 打赏
  • 举报
回复
上面居然用(OnPaint)重绘了,速度很慢的,可能还会闪哦,就算用虚拟模式也不能加快速度,OnPaint啊.
还是用3个datagridview吧,一个做表头,一个做表体,一个做页脚(可以合计,还能做其他的事情)
lwl0376 2007-12-28
  • 打赏
  • 举报
回复
关注
Efcndi 2007-12-28
  • 打赏
  • 举报
回复
GX LZ解决问题。

以前在自己写datagridcolumn的时候也遇到很多问题,一拖动就花屏了。
结果还是无能为力,一直等到dotnet修复了这个bug。
所以不会象lz那样自己去写控件了。

象这种多功能的datagrid控件,好像第三方的有不少。
学习精力有限吧,与其执着于界面上的问题,不如去学一些新东西。
不是都象lz那么牛的自己来!

高手少了。好几年前就这样了。
几年没上,我的老账号都丢了haha。

不知道可否加你为好友,有问题时向你请教!".."

九章落地 2007-12-28
  • 打赏
  • 举报
回复
TO:Ecndi
问题主要出在VerticalScrollingOffset,设scrollbar的maximun/minimun应该行不通.

我已通过重绘背景的方式解决了该难题.

回头来结帖,呵呵,感觉CSDN上的高手越来越少,上的次数越来越少,不知大伙是否有同感?
Efcndi 2007-12-28
  • 打赏
  • 举报
回复

hoho 已经加入好友了 ^_^
九章落地 2007-12-28
  • 打赏
  • 举报
回复
To:Efcndi

第三方控件,除了版权问题,要么不开源,要么太臃肿(像DEVELOPER EXPRESS),鉴于平时常用的也就那几个控件,才决定自己写.

由于我所在的团队没.net强人,写这个datagrid,花了不少时间.但越是这样,越要弄出个成果来,不然总觉得对不住之前投入的精力和时间.

非常乐意与你交流,共同进步 ^_^

Efcndi 2007-12-27
  • 打赏
  • 举报
回复

private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
DataGridView dgv = (DataGridView)sender;
dataGridView1.FirstDisplayedScrollingRowIndex = dgv.Rows.Count - 1
}
如果这样写在addrow的时候不会出现问题,但是当scrollbar拖动时问题仍然存在。
我已经找到一点思路就是修改scrollbar的maximun和minimun,使这个scrollbar正好能够位置对应。
问题产生的原因应该在于自己写的scrollbar无法整除这个offset。
这里其实就是个数值转换的问题。相信一定可以解决。

lovingkiss 2007-12-27
  • 打赏
  • 举报
回复
呵呵,我就不是这么做的,看我的下载基地

做成个控件多舒服啊,呵呵~~不复杂
==================================================================
博客空间:http://blog.csdn.net/lovingkiss
资源下载:http://download.csdn.net/user/lovingkiss
Email:loving-kiss@163.com
联系方式:Q66840199 全天在线
==================================================================
namhyuk 2007-12-27
  • 打赏
  • 举报
回复
可能和你的要求不符。
private void pictureBoxPageUp_Click(object sender, EventArgs e)
{
dataGridView1.Select();
SendKeys.Send("{PGUP}");
}

private void pictureBoxPageDown_Click(object sender, EventArgs e)
{
dataGridView1.Select();
SendKeys.Send("{PGDN}");
}
九章落地 2007-12-27
  • 打赏
  • 举报
回复
TO:Efcndi

我近段时间,想编一个控件,在现在的DataGridView上增加合并表头,及底部统计行.
前面我通过DataGridView里(OnPaint)重绘,功能都能做出来,如下图:


但有一个致使的缺点便是,当拖动滚动条时,有一点闪!

现在我通过组合控件的形式,用两个DataGridView+两个ScrollBar设计这样的控件,遇到了我此帖提到的怪问题...

郁闷呀!!!
qiqi1983731 2007-12-27
  • 打赏
  • 举报
回复
可以通过AllowUserToAddRows那个属性设置为false去掉那一行!
Efcndi 2007-12-27
  • 打赏
  • 举报
回复
一个取巧的方法是把ScrollBar的属性设置为Both。
把VScrollBar放在他自带的ScrollBar的前面,挡住他自带的。

问题是:LZ为什么需要这个自定义的VScrollBar,
而不是在datagridview的scroll事件中来设法调整scrollbar的位置?

考虑你的需求:要实现底部加合计行,那用户在addrow的时候是在你这个合计行的下方添加?
Efcndi 2007-12-27
  • 打赏
  • 举报
回复
我刚用SendMessage(datagridview,WM_VSCROLL)试了下,不行,效果还是一样。
只要把ScrollBar属性设为none,它就不会用原来的方法来画了。

到codeproject上也没有找到什么东东。

暂时没想到办法,听听5L的来说下。
九章落地 2007-12-27
  • 打赏
  • 举报
回复
TO:Efcndi
通过枚举DataGridView的子控件,可看到它确实包含了两个ScrollBar,但好像控制不了.

foreach (Control c in dataGridView1.Controls)
{
Console.WriteLine(c);
}


有一个很奇怪的现象是,如果我dataGridView1.ScrollBars = ScrollBars.Vertical;把它的垂直滚动条打开,我的外部ScrollBar操作DataGridView便能正常刷新.

集成ScrollBox和外部ScrollBax,通过比较发现,VerticalScrollingOffset属性值不一样,但VerticalScrollingOffset是只读属性,这才是烦人的地方.

大伙研究下,若能找到解决方案,过后定把控件的源码与大家分享

TO:
ouhou
我是绑定DataSource之后,在界面上手动输入内容,底部不能正常刷新
ouhou 2007-12-27
  • 打赏
  • 举报
回复
to 楼主,
“添加新记录时,DataGridView的最底部(默认显示背景色的一空栏)一直不能自动刷新,总会显示最后一行的列余,不能像默认的效果那样. ”

你是用代码添加的吧,用代码添加的时候没有触发UserAddedRow事件。
如果你在界面中直接向控件中输入内容,效果是和默认效果一样的
Efcndi 2007-12-27
  • 打赏
  • 举报
回复
确实有问题。
private void dataGridView1_UserAddedRow(object sender, DataGridViewRowEventArgs e)
{
vScrollBar1.Maximum += dataGridView1.RowTemplate.Height;
}
这里只改了scrollbar的信息是不行的。

刚找了一下如何取得datagridview的verticalscrollbar。
如果这个接口有开发出来,你把它隐藏了,再在你自己的scrollbar里委托它就很简单了。
不知道为什么没有这个接口。再找找看吧。
gimse7en 2007-12-27
  • 打赏
  • 举报
回复
学习
songle912 2007-12-27
  • 打赏
  • 举报
回复
难度,标记,学习
加载更多回复(4)

110,538

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧