Como posso fazer com que um painel para rolar programaticamente para expor sua picturebox AutoSize

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

  •  05-07-2019
  •  | 
  •  

Pergunta

Eu tenho um conjunto de caixa de imagem para AutoSize para que as forças de imagem que ela cresça para o tamanho máximo da imagem.

A caixa de imagem está em um painel com Autoscroll = true, de modo que as barras de rolagem aparecem quando a imagem é maior do que o painel.

Como posso programaticamente percorrer o painel como o usuário clica as drags na imagem, reposicionando assim a imagem.

Eu tentei aproveitou o evento MouseMove, capturando o último X e Y posições do mouse, calculando o quanto o mouse foi movido, e ajustou os valores Vertical e Horizontal de rolagem do painel.

O faz mover a imagem ao redor, mas ele salta por todo o lugar, e rola de forma imprevisível.

Como posso conseguir isso?

Aqui está o que eu tenho na minha Eventos de mouse ...

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

É o meu erro de lógica ou é o meu entendimento de rolagem funcionalidade errada do painel?

Foi útil?

Solução

Eu acredito que o seu instinto é correto, mas seu erro é tentar ajustar as barras de rolagem em vez de mover o PictureBox dentro do painel de rolagem.

Você deve interceptar o MouseMove e ajuste do PictureBox propriedade Location pelo delta movimento do mouse -. As barras de rolagem deve atualizar automaticamente para refletir a nova localização da imagem dentro dele

Como atualizar seu código seria algo parecido com tho seguinte (não testado):

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

(Além disso, eu estaria inclinado a gravar o mouse iniciar e locais PictureBox no início do arrastar e atualizá-los em relação a esta posição de partida em cada evento MouseMove ao invés de mudanças incrementais fazer como o código acima (e seu código original faz) a razão para isso é que, se existem quaisquer valores inesperados, por qualquer razão, então isso só irá causar um efeito transitório -.. o próximo evento bom se auto-corrigir)

Outras dicas

Ele está saltando porque o ato de rolagem do painel vai jogar fora a posição do mouse pela quantidade de rolagem. Você pode obter a posição do mouse "real" (relativo a partir do canto superior esquerdo do painel) assim:

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

assumindo a caixa de imagem' propriedade Location é (0, 0). A melhor maneira de percorrer o painel é definir sua propriedade AutoScrollPosition.

Você pode definir AutoScrollPosition do painel no evento MouseMove. Testado e funciona bem.

panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top