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

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

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

Какие-либо предложения?

Спасибо

Исаак

Ответы на вопрос(5)

отправив сообщение элементу управления с указанием прокрутки вверх или вниз.

Вот код, я надеюсь, это поможет:

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

 Isaac Bolinger23 янв. 2011 г., 10:01
Пробовал, и это не сработало. Сожалею!
 Isaac Bolinger23 янв. 2011 г., 08:01
Спасибо за это. Я не пробовал это ... у парня над тобой есть способ, не связанный с винапи.

HorizontalScrollingOffset / VerticalScrollingOffset изDataGridView

установить HorizontalScrollingOffset

dataGridView1.HorizontalScrollingOffset = dataGridView1.HorizontalScrollingOffset + 10;

проверить

Свойство DataGridView.HorizontScrollingOffset

а также

заVerticalScrollingOffset Вы можете использовать отражение

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

PropertyInfo verticalOffset = dataGridView1.GetType().GetProperty("VerticalOffset", BindingFlags.NonPublic | BindingFlags.Instance);
            verticalOffset.SetValue(this.dataGridView1, 10, null); 
 Javed Akram22 янв. 2011 г., 07:02
VerticalScrollingOffset имеет свойство только для чтения .. Таким образом, вы можете толькоget это не можетset Это.
 Isaac Bolinger23 янв. 2011 г., 08:02
Вау, я не знал, что вы можете использовать отражение, чтобы обойти свойства только для чтения. Это фактически прокручивает контроль. Спасибо большое за это!
 deadlock22 янв. 2011 г., 07:04
Не оба, Горизонтальный это {получить; set;} Хотя это ему так или иначе не поможет
 naveen25 янв. 2011 г., 08:12
+1 классное отражение приятель!
 Javed Akram22 янв. 2011 г., 07:06
@deadlock: Извините, только вертикальная галочка.

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

 Isaac Bolinger23 янв. 2011 г., 07:52
Да, мне просто нужно выяснить, как прокрутить его по строке!
 peterG13 дек. 2015 г., 22:14
На самом деле это работает хорошо даже без таймера! Похоже, что движение строк сетки под мышью достаточно для запуска события DragOver.
 Isaac Bolinger23 янв. 2011 г., 08:00
Ах, джентльмен ниже имеет решение. Я уже реализовал dragover, я добавлю туда немного кода, чтобы сделать его интеллектуальным, как вы предлагали. Спасибо за советы по дизайну, Ганс.
Решение Вопроса

winforms" в вопросе ... но я мог бы просто сделать это ... прокрутить вверх или вниз на один ряд.

Прокрутить вверх:

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex - 1

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

this.FirstDisplayedScrollingRowIndex = this.FirstDisplayedScrollingRowIndex + 1;

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

dgv.FirstDisplayedScrollingRowIndex = dgv.RowCount - 1;

Ваш ответ на вопрос