如何使面板以编程方式滚动以显示其自动调整大小的图片框

发布于 2024-08-13 01:09:30 字数 1890 浏览 9 评论 0原文

我将图片框设置为“自动大小”,以便图像强制其增长到图像的完整尺寸。

图片框位于面板中,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;
}

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

I have a picture box set to AutoSize so that the image forces it to grow to the image's full size.

The picture box is in a panel with autoScroll = true, so that scroll bars appear when the picture is larger than the panel.

How can I programmatically scroll the panel as the user clicks the drags on the image, thereby repositioning the image.

I've tried used the MouseMove event, capturing the last X and Y positions of the mouse, calculating how much the mouse has moved, and adjusted the Vertical and Horizontal Scroll values of the panel.

The does move the image around, but it jumps all over the place, and scrolls unpredictably.

How can I achieve this?

Here's what I have in my Mouse events...

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

Is my logic wrong or is my understanding of the panel's scrolling functionality wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

凉薄对峙 2024-08-20 01:09:30

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

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

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

It is jumping because the act of scrolling the panel will throw off the mouse position by the scroll amount. You can get the "real" mouse position (relative from the upper left corner of the panel) like this:

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

assuming the picture box' Location property is (0, 0). The best way to scroll the panel is to set its AutoScrollPosition property.

沉鱼一梦 2024-08-20 01:09:30

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

I believe your instinct is correct but your mistake is to attempt to adjust the scrollbars rather than moving the PictureBox within the scrollable panel.

You should intercept the MouseMove and adjust the PictureBox's Location property by the mouse movement delta — the scrollbars should automatically update to reflect the image's new location within it.

Updating your code would look something like tho following (untested):

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

(Also, I would be inclined to record the starting mouse and PictureBox locations at the start of the drag and update them relative to this starting position on each MouseMove event rather than make incremental changes as the code above (and your original code does). The reason for this is that if there are any unexpected values, for whatever reason, then this will only cause a transitory effect — the next good event will self-correct.)

闻呓 2024-08-20 01:09:30

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

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

You can set the panel's AutoScrollPosition in MouseMove event. Tested and works fine.

panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文