如何以编程方式滚动winforms datagridview控件?

时间:2011-01-22 05:49:30

标签: winforms datagridview scroll

我在一个继承自datagridview的控件中实现了一些拖放功能。基本上我是从DGV中的某处拖动一行并将其放在其他地方,重新排序行。我遇到了一个问题。如果DGV太大而没有滚动条,那么当用户处于拖车中间时,如何让DGV向上或向下滚动?

我知道如何获取当前鼠标位置并获得dgv矩形的位置等。所以,我可以很容易地发现我是在矩形的顶部还是下半部分...我只需要一种以编程方式滚动dgv的方法。我更愿意,如果我不必继续更改所选单元格来执行此操作。

有什么建议吗?

由于

艾萨克

6 个答案:

答案 0 :(得分:19)

好吧,因为这是一个datagridview ...对于问题中的'winforms'抱歉...但我可以这样做......向上或向下滚动一行。

向上滚动:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex - 1

向下滚动:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex + 1;

你必须确保检查数字是否超出范围。

答案 1 :(得分:11)

您可以通过设置HorizontalScrollingOffset

VerticalScrollingOffset / DataGridView来执行此操作

设置Horizo​​ntalScrollingOffset

dataGridView1.HorizontalScrollingOffset = dataGridView1.HorizontalScrollingOffset + 10;

检查

DataGridView.HorizontalScrollingOffset Property

VerticalScrollingOffset您可以使用反射

包含名称空间System.Reflection

PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic | BindingFlags.Instance);
            verticalOffset.SetValue(this.dataGridView1, 10, null); 

答案 2 :(得分:5)

您可以通过向控件发送消息告诉它向上或向下滚动来使用WinAPI。

这是代码,我希望它有所帮助:

private const int WM_SCROLL = 276; // Horizontal scroll
private const int WM_VSCROLL = 277; // Vertical scroll
private const int SB_LINEUP = 0; // Scrolls one line up
private const int SB_LINELEFT = 0;// Scrolls one cell left
private const int SB_LINEDOWN = 1; // Scrolls one line down
private const int SB_LINERIGHT = 1;// Scrolls one cell right
private const int SB_PAGEUP = 2; // Scrolls one page up
private const int SB_PAGELEFT = 2;// Scrolls one page left
private const int SB_PAGEDOWN = 3; // Scrolls one page down
private const int SB_PAGERIGTH = 3; // Scrolls one page right
private const int SB_PAGETOP = 6; // Scrolls to the upper left
private const int SB_LEFT = 6; // Scrolls to the left
private const int SB_PAGEBOTTOM = 7; // Scrolls to the upper right
private const int SB_RIGHT = 7; // Scrolls to the right
private const int SB_ENDSCROLL = 8; // Ends scroll

[DllImport("user32.dll",CharSet=CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg,IntPtr wParam, IntPtr lParam);

现在假设您的表单上有一个文本框控件。您可以使用以下方式移动它:

SendMessage(textBox1.Handle,WM_VSCROLL,(IntPtr)SB_PAGEUP,IntPtr.Zero); //ScrollUp
SendMessage(textBox1.Handle,WM_VSCROLL,(IntPtr)SB_PAGEDOWN,IntPtr.Zero); //ScrollDown

如果这种经典的通用解决方案不适合您。您可能需要查看FirstDisplayedScrollingRowIndex属性,并在拖动过程中更改鼠标位置。

答案 3 :(得分:4)

dgv.FirstDisplayedScrollingRowIndex = dgv.RowCount - 1;

答案 4 :(得分:2)

您需要实现DragOver事件。检查鼠标是否位于控件的顶部或底部附近(使用PointToClient)。如果是,则启用间隔为~200毫秒的计时器。在Tick事件处理程序中,按行滚动DGV。当鼠标未关闭且DoDragDrop返回后禁用计时器。用户现在可以轻松直观地滚动网格,只是在末端附近徘徊。

答案 5 :(得分:0)

以 MaxEcho 的答案为基础进行回答。您可以覆盖 DataGridView 的 OnScroll 事件。此方法中的 eventArgs 包含第一个可见行号。您可以将此行号传递给另一个 DataGridView,并设置 FirstDisplayedScrollRowIndex 使其滚动到该位置。

唯一的问题是装饰性的,如果滚动速度非常快,第二个 datagridview 会暂停更新/动画并在滚动速度变慢时闪烁到活动行。

client = commands.Bot(..)