マウスボタンのダウン、アップイベントと移動イベントのマウス座標をもとに矩形領域を作成しPathで描画しています。
矩形選択機能の試作ということで座標系の動作確認用としてプログラムを作成してみみました。
using System.Drawing.Drawing2D;
namespace PictureBox04;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Size = new Size(256, 256);
var bmp = new Bitmap(512, 512);
using(var g = Graphics.FromImage(bmp))
{
g.Clear(Color.Blue);
var rect = new Rectangle(64, 64, 128, 128);
var rect2 = new Rectangle(64+128, 64+128, 128, 128);
g.FillPie(Brushes.White, rect, 0f, 360f);
g.FillRectangle(Brushes.White, rect2);
}
var panel1 = new Panel()
{
AutoScroll = true,
Dock = DockStyle.Fill,
Parent = this,
};
var picbox1 = new PictureBox()
{
SizeMode = PictureBoxSizeMode.AutoSize,
Image = bmp,
Parent = panel1,
};
int x1 = -1;
int y1 = -1;
int x2 = -1;
int y2 = -1;
bool mouseMoving = false;
Pen pen1 = new Pen(Brushes.Black, 3.0f);
GraphicsPath path1 = new();
// ピクチャボックス上のマウスダウンイベント
picbox1.MouseDown += (s, e) =>
{
x1 = e.Location.X;
y1 = e.Location.Y;
x2 = -1;
y2 = -1;
mouseMoving = true;
};
// ピクチャボックス上のマウスの移動イベント
picbox1.MouseMove += (s, e) =>
{
if (mouseMoving == true)
{
int x = e.Location.X;
int y = e.Location.Y;
var rect = new Rectangle(x1, y1, x-x1, y-y1);
path1?.Dispose();
path1 = new GraphicsPath();
path1.AddRectangle(rect);
picbox1.Invalidate();
}
};
// ピクチャボックス再描画
picbox1.Paint += (s, e) =>
{
if (mouseMoving)
e.Graphics.DrawPath(pen1, path1);
};
// ピクチャボックス上のマウスアップ
picbox1.MouseUp += (s, e) =>
{
x2 = e.Location.X;
y2 = e.Location.Y;
mouseMoving = false;
};
}
}
大きな画像をスクロールを使って表示する場合、スクロール位置がマウスの座標に影響があるかと思い、それを確認するためのプログラムでしたが、単純にPictureBoxのマウスのイベントの座標を拾うことで、スクロール位置を加味した座標になっていいました。マウスダウンで矩形の左上の座標、マウスアップで右下の座標を取得します。また、マウスの移動イベントでも矩形選択の途中経過を表示する表示するように、座標を取得しInvalidate()を実行してPaintイベントを発生させています。
Paintイベントでは取得した矩形座標をもとにPathで矩形を描画しています。
コメント