Как сделать так, чтобы панель прокручивалась программно, чтобы выставить ее AutoSize Picturebox
-
05-07-2019 - |
Вопрос
Я установил для AutoSize графический блок, чтобы изображение увеличивало его до полного размера.
Окно рисунка находится на панели с autoScroll = true, поэтому полосы прокрутки появляются, когда изображение больше, чем панель.
Как программно прокрутить панель, когда пользователь нажимает на перетаскивание изображения, тем самым изменяя положение изображения.
Я пытался использовать событие MouseMove, захватывая последние X и Y позиции мыши, вычисляя, сколько мышь переместила, и корректировал значения вертикальной и горизонтальной прокрутки панели.
The действительно перемещает изображение, но оно скачет повсюду и непредсказуемо прокручивается.
Как мне этого добиться?
Вот что у меня есть в событиях мыши ...
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
if (e.Button == MouseButtons.Left)
{
// move the image inverse to direction dragged
int horizontalChange = (e.X - startingX) * -1;
int newHorizontalPos = panel1.HorizontalScroll.Value + horizontalChange;
if (newHorizontalPos < panel1.HorizontalScroll.Minimum)
{
newHorizontalPos = panel1.HorizontalScroll.Minimum;
horizontalChange = 0;
}
if (newHorizontalPos > panel1.HorizontalScroll.Maximum)
{
newHorizontalPos = panel1.HorizontalScroll.Maximum;
horizontalChange = 0;
}
panel1.HorizontalScroll.Value = newHorizontalPos;
int verticalChange = (e.Y - startingY);
// move the image inverse to direction dragged
int newverticalPos = panel1.VerticalScroll.Value + verticalChange * -1;
if (newverticalPos < panel1.VerticalScroll.Minimum)
{
newverticalPos = panel1.VerticalScroll.Minimum;
verticalChange = 0;
}
if (newverticalPos > panel1.VerticalScroll.Maximum)
{
newverticalPos = panel1.VerticalScroll.Maximum;
verticalChange = 0;
}
panel1.VerticalScroll.Value = newverticalPos;
}
}
startingX = e.X;
startingY = e.Y;
}
Моя логика неверна или мое понимание функций прокрутки панели неверно?
Решение
Я считаю, что ваш инстинкт верен, но ваша ошибка - попытаться настроить полосы прокрутки, а не перемещать PictureBox в пределах прокручиваемой панели.
Вам необходимо перехватить MouseMove и настроить свойство Location PictureBox с помощью дельты движения мыши & # 8212; полосы прокрутки должны автоматически обновиться, чтобы отразить новое местоположение изображения в нем.
Обновление вашего кода будет выглядеть примерно так: (не проверено):
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (dragging)
{
if (e.Button == MouseButtons.Left)
{
int horizontalChange = (e.X - startingX) * -1; // move the image inverse to direction dragged
int verticalChange = (e.Y - startingY);
pictureBox1.Left += horizontalChange;
pictureBox1.Top += verticalChange;
}
}
startingX = e.X;
startingY = e.Y;
}
(Кроме того, я был бы склонен записывать начальную позицию мыши и PictureBox в начале перетаскивания и обновлять их относительно этой начальной позиции в каждом событии MouseMove, а не вносить инкрементные изменения, как код выше (и ваш исходный код делает). Причина в том, что если по какой-либо причине будут какие-либо неожиданные значения, то это вызовет только временный эффект - следующее хорошее событие будет самокорректироваться.)
Другие советы
Он прыгает, потому что при прокрутке панели смещается позиция мыши на величину прокрутки. Вы можете получить " реальный " положение мыши (относительно левого верхнего угла панели) примерно так:
Point realPos = new Point(e.X + panel1.AutoScrollPosition.X,
e.Y + panel1.AutoScrollPosition.Y);
при условии, что свойство Location графического блока имеет значение (0, 0). Лучший способ прокрутки панели - установить ее свойство AutoScrollPosition.
Вы можете установить AutoScrollPosition
панели в событии MouseMove. Протестировано и отлично работает.
panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);