パネルをプログラムでスクロールさせてAutoSizeピクチャボックスを公開するにはどうすればよいですか

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

  •  05-07-2019
  •  | 
  •  

質問

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

ロジックが間違っているか、パネルのスクロール機能の理解が間違っていますか

役に立ちましたか?

解決

あなたの本能は正しいと思いますが、あなたの間違いは、スクロール可能なパネル内でPictureBoxを移動するのではなく、スクロールバーを調整しようとすることです。

MouseMoveをインターセプトし、マウス移動デルタによってPictureBoxのLocationプロパティを調整する必要があります&#8212;スクロールバーは自動的に更新され、その中の画像の新しい場所が反映されます。

コードを更新すると、次のようになります(テストされていません):

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の位置を記録し、上記のコード(および元のコードこの理由は、何らかの理由で予期しない値が存在する場合、一時的な効果のみが発生するためです;&#8212;次の良いイベントは自己修正します。)

他のヒント

パネルをスクロールすると、スクロール量だけマウスの位置がずれるため、ジャンプします。 「本物」を取得できます。次のようなマウス位置(パネルの左上隅からの相対位置):

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

ピクチャボックスのLocationプロパティが(0、0)であると仮定します。パネルをスクロールする最良の方法は、AutoScrollPositionプロパティを設定することです。

MouseMoveイベントでパネルの AutoScrollPosition を設定できます。テスト済みで正常に動作しています。

panel1.AutoScrollPosition = new Point(-panel1.AutoScrollPosition.X - e.X + startPoint.X, -panel1.AutoScrollPosition.Y - e.Y + startPoint.Y);
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top