Как сделать так, чтобы панель прокручивалась программно, чтобы выставить ее AutoSize Picturebox

StackOverflow https://stackoverflow.com/questions/1803191

  •  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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top