Como posso fazer com que um painel para rolar programaticamente para expor sua picturebox AutoSize
-
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?
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);