2011-01-22 2 views
11

Я реализую некоторые функции перетаскивания в одном из моих элементов управления, наследующих от datagridview. В основном я перетаскиваю строку откуда-то в DGV и отбрасываю ее в другое место, переупорядочивая строки. Однако я столкнулся с проблемой. Если DGV слишком велик, так что есть полоса прокрутки, как я могу прокручивать DGV вверх или вниз, пока пользователь находится в середине перетаскивания?Как программно прокручивать элемент управления datagridview winforms?

Я знаю, как получить текущую позицию мыши, а также получить положение прямоугольника dgv и т. Д. Итак, я могу легко узнать, есть ли я в верхней или нижней половине прямоугольника ... Мне просто нужен способ программно прокрутить dgv. Я бы предпочел, если мне не придется менять выбранную ячейку, чтобы сделать это.

Любые предложения?

Благодаря

Исаак

ответ

18

Ну, так как это datagridview ... Извините за «winforms» в вопросе ... но я мог просто сделать это .. прокручивание вверх или вниз по одной строке.

Прокрутка вверх:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex - 1 

Прокрутка вниз:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex + 1; 

Ты должен убедиться, чтобы проверить, что номера не выходят за пределы, хотя.

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 Свойство и изменить его относительно позиции мыши во время перетаскивания.

+0

Благодарим за это. Я не пробовал это. У парня выше вас есть способ не winapi сделать это. –

+0

Пробовал, и это не сработало. Сожалею! –

9

вы можете сделать это, установив HorizontalScrollingOffset/VerticalScrollingOffset из DataGridView

установить HorizontalScrollingOffset

dataGridView1.HorizontalScrollingOffset = dataGridView1.HorizontalScrollingOffset + 10; 

проверка

DataGridView.HorizontalScrollingOffset Property

и

для VerticalScrollingOffset вы можете использовать Reflection

включают пространство имен System.Reflection

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

VerticalScrollingOffset имеет свойство только для чтения. Таким образом, вы можете только «получить» его, не можете «установить» его. –

+0

Не оба, Горизонтальный {get; set;} Хотя это не поможет ему так или иначе – deadlock

+0

@deadlock: Извините, проверено только по вертикали .. –

2

Вы должны реализовать событие DragOver. Проверьте, находится ли мышь близко к верхней или нижней части элемента управления (используйте PointToClient). Когда это так, включите таймер с интервалом ~ 200 мс. В обработчике события Tick прокрутите DGV по строке. Отключите таймер, когда мышь не закрыта и после возврата DoDragDrop. Теперь пользователь может легко и интуитивно прокручивать сетку, только находясь рядом с концами.

+0

Да, мне просто нужно выяснить, как прокручивать его по строке! –

+0

Ах, у джентльмена ниже есть решение. У меня уже есть dragover, я добавлю там код, чтобы он прокручивался разумно, как вы предлагали. Спасибо за ваш совет по дизайну Ганса. –

+0

На самом деле это хорошо работает даже без таймера! Кажется, что перемещение строк сетки под мышью достаточно, чтобы продолжать стрелять из события DragOver. – peterG

Смежные вопросы