如何使面板以编程方式滚动以显示其AutoSize图片框

时间:2009-11-26 11:39:29

标签: c# winforms panel picturebox

我将图片框设置为AutoSize,以便图像强制它增长到图像的全尺寸。

图片框位于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 个答案:

答案 0 :(得分:5)

它是跳跃的,因为滚动面板的动作将通过滚动量甩开鼠标位置。你可以得到“真正的”鼠标位置(相对于面板的左上角),如下所示:

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

假设图片框'Location属性为(0,0)。滚动面板的最佳方法是设置其AutoScrollPosition属性。

答案 1 :(得分:4)

我相信你的直觉是正确的,但你的错误是尝试调整滚动条而不是在可滚动面板中移动PictureBox。

您应截取MouseMove并通过鼠标移动增量调整PictureBox的Location属性 - 滚动条应自动更新以反映图像中的新位置。

更新您的代码看起来像以下(未经测试):

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事件上相对于此起始位置更新它们,而不是像上面的代码那样进行增量更改(和原始代码)这样做的原因是,如果有任何意外的值,无论出于何种原因,那么这只会造成短暂的影响 - 下一个好事件会自我纠正。)

答案 2 :(得分:3)

您可以在MouseMove事件中设置面板的AutoScrollPosition。经过测试并且工作正常。

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