スクロールバー付きのピクチャーボックスでBitmapを移動させます。Bitmapをドラッグで移動させる場合、その都度PictureBox.Imageにセットするbitmapを生成していては処理が重くなります。Paintイベントを処理することでBitmapを表示させます。
そのためにMovableBitmapクラスを作成します。PictureBoxプロパティは実際にBitmapが描画されるピクチャーボックスです。Bitmap, X, Y, Width, Heightプロパティが変更されるとPictureBox.Invalidate()を呼び出して再描画させます。
Keyプロパティは同じオブジェクトを探すための手がかりになる文字列です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
public class MovableBitmap { public MovableBitmap(Bitmap bitmap) { Bitmap = bitmap; } internal PictureBox PictureBox { get; set; } = null; Bitmap _bitmap = null; public Bitmap Bitmap { get { return _bitmap; } set { _bitmap = value; if (value != null) { Width = value.Width; Height = value.Height; } else { Width = 0; Height = 0; } if (PictureBox != null) PictureBox.Invalidate(); } } public string Key { get; set; } int _x = 0; public int X { get { return _x; } set { _x = value; if (PictureBox != null) PictureBox.Invalidate(); } } int _y = 0; public int Y { get { return _y; } set { _y = value; if (PictureBox != null) PictureBox.Invalidate(); } } int _width = 0; public int Width { get { return _width; } set { _width = value; if (PictureBox != null) PictureBox.Invalidate(); } } int _height = 0; public int Height { get { return _height; } set { _height = value; if (PictureBox != null) PictureBox.Invalidate(); } } public int Left { get { return X; } } public int Right { get { return X + Width; } } public int Top { get { return Y; } } public int Bottom { get { return Y + Height; } } } |
ScrollPictureBoxクラスにMovableBitmapオブジェクトを格納するリストを作成し、ここにMovableBitmapを格納するときにPictureBoxプロパティにpictureBox1をセットします。これでX、Yプロパティが変更されたときに表示場所が変更されます。
GetMovableBitmap(string key)メソッドはKeyプロパティから、GetFirstMovableBitmap(Point point)メソッドは座標(PictureBoxコントロール上の座標ではなくピクセル座標)から対応するMovableBitmapを探します。そしてPaintイベントが発生するとMovableBitmaps内のオブジェクトを適切な位置に描画します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
public partial class ScrollPictureBox : UserControl { List<MovableBitmap> MovableBitmaps = new List<MovableBitmap>(); public void AddMovableBitmap(MovableBitmap obj) { obj.PictureBox = this.pictureBox1; MovableBitmaps.Add(obj); pictureBox1.Invalidate(); } public MovableBitmap GetMovableBitmap(string key) { return MovableBitmaps.FirstOrDefault(x => x.Key == key); } public MovableBitmap GetFirstMovableBitmap(Point point) { return MovableBitmaps.FirstOrDefault(x => IsRect(x, point)); } public void ClearMovableBitmap() { MovableBitmaps.Clear(); pictureBox1.Invalidate(); } bool IsRect(MovableBitmap obj, Point pt) { if (pt.X < obj.Left) return false; if (obj.Right < pt.X) return false; if (pt.Y < obj.Top) return false; if (obj.Bottom < pt.Y) return false; return true; } private void PictureBox1_Paint(object sender, PaintEventArgs e) { DrawByDrag.Draw(e.Graphics); int width = 0; int height = 0; if (pictureBox1.Image != null) { width = pictureBox1.Image.Width; height = pictureBox1.Image.Height; } if (MovableBitmaps.Count > 0) { int right = (int)(MovableBitmaps.Max(x => x.Right) * Expansionrate); int bottom = (int)(MovableBitmaps.Max(x => x.Bottom) * Expansionrate); if (width < right) width = right; if (height < bottom) height = bottom; } if (width > 0 && height > 0) { if (pictureBox1.Size != new Size(width, height)) pictureBox1.Size = new Size(width, height); } foreach (MovableBitmap obj in MovableBitmaps) { int x = (int)(obj.X * Expansionrate); int y = (int)(obj.Y * Expansionrate); int w = (int)(obj.Width * Expansionrate); int h = (int)(obj.Height * Expansionrate); e.Graphics.DrawImage(obj.Bitmap, new Rectangle(x, y, w, h)); } PictureBoxPaint?.Invoke(this, e); } } |
試運転。ダイアログで選択されたPngファイルを描画します。そして画像がドラッグされると移動処理をおこないます。
クリックされた場所にBitmapが存在するかGetFirstMovableBitmapメソッドで調べます。存在する場合はそのオブジェクトともとの位置をフィールド変数に保存します。マウスが移動するともとの位置と移動距離から新しいオブジェクトの位置を計算し、Bitmapをその場所に描画します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
public partial class Form1 : Form { List<string> Vs = new List<string>(); private void button1_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "画像ファイル|*.png"; if (dlg.ShowDialog() == DialogResult.OK) { try { Bitmap bitmap = new Bitmap(dlg.FileName); string key = DateTime.Now.ToString(); Vs.Add(key); MovableBitmap obj = new MovableBitmap(bitmap); obj.Key = key; scrollPictureBox1.AddMovableBitmap(obj); } catch { } } dlg.Dispose(); } // 移動中のMovableBitmapと移動を開始する前の座標 MovableBitmap MovingBitmap = null; int OldBmpPosX = 0; int OldBmpPosY = 0; private void scrollPictureBox1_PictureBoxMouseDown1(object sender, ScrollPictureBoxLib.PictureBoxMouseEventArgs e) { ScrollPictureBoxLib.MovableBitmap obj = scrollPictureBox1.GetFirstMovableBitmap(new Point(e.PixelX, e.PixelY)); if (obj != null) { MovingBitmap = obj; OldBmpPosX = obj.X; OldBmpPosY = obj.Y; } } private void scrollPictureBox1_PictureBoxMouseMove1(object sender, ScrollPictureBoxLib.PictureBoxMouseEventArgs e) { if (MovingBitmap != null) { MovingBitmap.X = OldBmpPosX + e.PixelMoveX; MovingBitmap.Y = OldBmpPosY + e.PixelMoveY; } } private void scrollPictureBox1_PictureBoxMouseUp1(object sender, ScrollPictureBoxLib.PictureBoxMouseEventArgs e) { if (MovingBitmap != null) { MovingBitmap.X = OldBmpPosX + e.PixelMoveX; MovingBitmap.Y = OldBmpPosY + e.PixelMoveY; MovingBitmap = null; } } } |