【问题标题】:How can I cause a panel to scroll programatically to expose its AutoSized picture box如何使面板以编程方式滚动以显示其 AutoSize 图片框
【发布时间】:2010-12-20 15:58:02
【问题描述】:

我有一个设置为 AutoSize 的图片框,以便图像强制它增长到图像的完整大小。

图片框在autoScroll = true的panel中,这样当图片大于panel的时候会出现滚动条。

如何在用户单击图像上的拖动时以编程方式滚动面板,从而重新定位图像。

我尝试使用 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;
}

是我的逻辑错了还是我对面板滚动功能的理解错了?

【问题讨论】:

    标签: c# winforms panel picturebox


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      它是跳跃的,因为滚动面板的动作会使鼠标位置偏离滚动量。您可以像这样获得“真实”鼠标位置(相对于面板左上角):

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

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

      【讨论】:

        【解决方案3】:

        我相信您的直觉是正确的,但您的错误是尝试调整滚动条而不是在可滚动面板内移动 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 事件上相对于该起始位置更新它们,而不是像上面的代码(以及您的原始代码)那样进行增量更改确实)。这样做的原因是,如果有任何意外的值,无论出于何种原因,这只会造成暂时的影响——下一个好的事件会自我纠正。)

        【讨论】:

        • 谢谢。我正在使用这种方法。如果您将图片框从顶部或左侧移开,面板控件不会显示滚动条:-(
        • 哦,这很奇怪——如果你打开了 AutoScroll,它确实应该这样做。
        猜你喜欢
        • 2013-07-19
        • 2016-08-29
        • 1970-01-01
        • 2018-06-01
        • 1970-01-01
        • 2018-11-22
        • 2021-04-19
        • 2012-07-23
        • 2014-09-14
        相关资源
        最近更新 更多