Как программно прокручивать элемент управления datagridview winforms?
Я реализую некоторые функции перетаскивания в одном из моих элементов управления, наследующих от datagridview. В основном я перетаскиваю строку откуда-то в DGV и отбрасываю ее в другое место, переупорядочивая строки. Однако я столкнулся с проблемой. Если DGV слишком велик, так что есть полоса прокрутки, как я могу прокручивать DGV вверх или вниз, когда пользователь находится в середине перетаскивания?
Я знаю, как получить текущую позицию мыши, а также получить положение прямоугольника dgv и т.д. Итак, я могу легко узнать, есть ли я в верхней или нижней половине прямоугольника... Мне просто нужен способ программно прокрутить dgv. Я бы предпочел, если мне не придется менять выбранную ячейку, чтобы сделать это.
Любые предложения?
Спасибо
Isaac
Ответы
Ответ 1
Ну, так как это datagridview... Извините за "winforms" в вопросе... но я мог бы просто сделать это.. прокрутка вверх или вниз по одной строке.
Прокрутка вверх:
this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex - 1
Прокрутка вниз:
this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex + 1;
Вы должны убедиться, что цифры не выходят за границы, хотя.
Ответ 2
вы можете сделать это, установив HorizontalScrollingOffset
/VerticalScrollingOffset
в DataGridView
установить HorizontalScrollingOffset
dataGridView1.HorizontalScrollingOffset = dataGridView1.HorizontalScrollingOffset + 10;
проверить
Свойство DataGridView.HorizontalScrollingOffset
и
для VerticalScrollingOffset
вы можете использовать Reflection
include namespace System.Reflection
PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic | BindingFlags.Instance);
verticalOffset.SetValue(this.dataGridView1, 10, null);
Ответ 3
Вы можете сделать это с помощью 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 Свойство и изменить его относительно положения мыши во время перетаскивания.
Ответ 4
dgv.FirstDisplayedScrollingRowIndex = dgv.RowCount - 1;
Ответ 5
Вам нужно реализовать событие DragOver. Проверьте, находится ли мышь близко к верхней или нижней части элемента управления (используйте PointToClient). Когда это так, включите таймер с интервалом ~ 200 мс. В обработчике события Tick прокрутите DGV по строке. Отключите таймер, когда мышь не закрыта и после возврата DoDragDrop. Теперь пользователь может легко и интуитивно прокручивать сетку, только находясь рядом с концами.