Как сделать так, чтобы панель прокручивалась программно, чтобы выставить окно авторазмера? - PullRequest
7 голосов
/ 26 ноября 2009

У меня есть окно изображения, установленное на Авторазмер, так что изображение заставляет его расти до полного размера изображения.

Поле рисунка находится на панели с autoScroll = true, поэтому полосы прокрутки появляются, когда изображение больше, чем панель.

Как программно прокрутить панель, когда пользователь нажимает на перетаскивание изображения, тем самым изменяя положение изображения.

Я пытался использовать событие MouseMove, захватывая последние X и Y позиции мыши, вычисляя, сколько мышь переместила, и корректировал значения вертикальной и горизонтальной прокрутки панели.

Это действительно перемещает изображение, но оно скачет повсюду и непредсказуемо прокручивается.

Как мне этого добиться?

Вот что у меня есть в событиях с мышью ...

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;
}

Моя логика неверна или мое понимание функции прокрутки панели неверно?

Ответы [ 3 ]

5 голосов
/ 26 ноября 2009

Он прыгает, потому что прокрутка панели отбросит позицию мыши на величину прокрутки. Вы можете получить «реальную» позицию мыши (относительно верхнего левого угла панели) следующим образом:

  Point realPos = new Point(e.X + panel1.AutoScrollPosition.X,
    e.Y + panel1.AutoScrollPosition.Y);

при условии, что в графическом окне 'свойство Location (0, 0). Лучший способ прокрутки панели - установить ее свойство AutoScrollPosition.

4 голосов
/ 26 ноября 2009

Я считаю, что ваш инстинкт верен, но ваша ошибка состоит в том, что вы пытаетесь настроить полосы прокрутки, а не перемещать PictureBox в пределах прокручиваемой панели.

Вам следует перехватить MouseMove и настроить свойство Location PictureBox с помощью дельты движения мыши - полосы прокрутки должны автоматически обновиться, чтобы отразить новое местоположение изображения в нем.

Обновление вашего кода будет выглядеть примерно так (не проверено):

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, а не вносить инкрементные изменения, как код выше (и ваш исходный код делает). Причина этого заключается в том, что если по какой-либо причине будут какие-либо неожиданные значения, то это вызовет только временный эффект - следующее хорошее событие будет самокорректироваться.)

3 голосов
/ 02 июня 2016

Вы можете установить AutoScrollPosition панели в событии MouseMove. Проверено и отлично работает.

panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);
...