前提・実現したいこと
C#で図形を描きその図形にマウスが乗ったら色が変わるというアプリケーションを作成しているのですが
発生している問題・エラーメッセージ
イベントハンドラがいまいちわかりません。このソースコードの場合は何に対してイベントを起こせばよいのでしょうか?
該当のソースコード
private void Form1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; int a = 2; int b = 2; int c = 150; int d = 150; for (int x = 1; x < 200; ++x) { a += 4; b += 2; g.DrawRectangle(Pens.Blue, a, b, c, d); } a = 800; b = 2; for (int x = 1; x < 200; ++x) { a -= 4; b += 2; g.DrawRectangle(Pens.Blue, a, b, c, d); }
試したこと
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
TN8001が👍を押しています
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
Form のイベントが起こった時のマウスカーソルの位置から計算する。
回答2件
0
ベストアンサー
FillRectangle
相当になってしまいますが、こんなのはどうでしょう?
図形の保存やヒットテスト等、面倒なことをパネルにお任せしてしまいます(図形をGraphicsPath
にするのがすこし手間ですが)
cs
1using System; 2using System.Drawing; 3using System.Drawing.Drawing2D; 4using System.Windows.Forms; 5 6namespace Questions260581 7{ 8 public partial class Form1 : Form 9 { 10 public Form1() 11 { 12 InitializeComponent(); 13 ClientSize = new Size(1000, 600); 14 15 var left = 2; 16 var top = 2; 17 var width = 150; 18 var height = 150; 19 20 for(var x = 1; x < 200; ++x) 21 { 22 left += 4; 23 top += 2; 24 25 var panel = new Panel 26 { 27 Top = top, 28 Left = left, 29 Width = width, 30 Height = height, 31 BackColor = Color.Blue, 32 }; 33 panel.MouseEnter += Panel_MouseEnter; 34 panel.MouseLeave += Panel_MouseLeave; 35 Controls.Add(panel); 36 } 37 38 left = 800; 39 top = 2; 40 41 var path = new GraphicsPath(FillMode.Winding); 42 path.AddLines(StarPoints(5, new Rectangle(0, 0, width, height))); 43 var region = new Region(path); 44 45 for(var x = 1; x < 200; ++x) 46 { 47 left -= 4; 48 top += 2; 49 50 var panel = new Panel 51 { 52 Top = top, 53 Left = left, 54 Width = width, 55 Height = height, 56 BackColor = Color.Blue, 57 Region = region, 58 }; 59 60 panel.MouseEnter += Panel_MouseEnter; 61 panel.MouseLeave += Panel_MouseLeave; 62 Controls.Add(panel); 63 } 64 } 65 66 private void Panel_MouseEnter(object sender, EventArgs e) 67 { 68 if(sender is Panel p) 69 { 70 p.BackColor = Color.Red; 71 p.BringToFront(); 72 } 73 } 74 75 private void Panel_MouseLeave(object sender, EventArgs e) 76 { 77 if(sender is Panel p) 78 { 79 p.BackColor = Color.Blue; 80 } 81 } 82 83 //http://csharphelper.com/blog/2014/08/draw-a-star-in-c/ 84 private PointF[] StarPoints(int num_points, Rectangle bounds) 85 { 86 var pts = new PointF[num_points]; 87 88 double rx = bounds.Width / 2; 89 double ry = bounds.Height / 2; 90 var cx = bounds.X + rx; 91 var cy = bounds.Y + ry; 92 93 var theta = -Math.PI / 2; 94 var dtheta = 4 * Math.PI / num_points; 95 for(var i = 0; i < num_points; i++) 96 { 97 pts[i] = new PointF( 98 (float)(cx + rx * Math.Cos(theta)), 99 (float)(cy + ry * Math.Sin(theta))); 100 theta += dtheta; 101 } 102 103 return pts; 104 } 105 } 106}
追記 雑な自前描画版
cs
1using System.Collections.Generic; 2using System.Drawing; 3using System.Drawing.Drawing2D; 4using System.Windows.Forms; 5 6namespace Questions260581 7{ 8 public partial class Form1 : Form 9 { 10 private readonly List<GraphicsPath> paths = new List<GraphicsPath>(); 11 private GraphicsPath selected = new GraphicsPath(); // nullチェックが面倒なのでカラのパス 12 13 public Form1() 14 { 15 InitializeComponent(); 16 ClientSize = new Size(1000, 600); 17 MouseMove += Form1_MouseMove; 18 19 var left = 2; 20 var top = 2; 21 var width = 150; 22 var height = 150; 23 24 for(var x = 1; x < 200; ++x) 25 { 26 left += 4; 27 top += 2; 28 29 var path = new GraphicsPath(); 30 path.AddRectangle(new Rectangle(left, top, width, height)); 31 paths.Add(path); 32 } 33 34 left = 800; 35 top = 2; 36 var lines = new PointF[] // StarPoints()が閉じてくれていないので手打ち^^; 37 { 38 new PointF(75f, 0f), 39 new PointF(119.0839f, 135.6763f), 40 new PointF(3.670761f, 51.82373f), 41 new PointF(146.3292f, 51.82373f), 42 new PointF(30.91611f, 135.6763f), 43 new PointF(75f, 0f), 44 }; 45 for(var x = 1; x < 200; ++x) 46 { 47 left -= 4; 48 top += 2; 49 50 var path = new GraphicsPath(); 51 path.AddLines(lines); 52 var matrix = new Matrix(); 53 matrix.Translate(left, top, MatrixOrder.Append); 54 path.Transform(matrix); 55 paths.Add(path); 56 } 57 } 58 59 private void Form1_MouseMove(object sender, MouseEventArgs e) 60 { 61 foreach(var path in paths) 62 { 63 if(!path.IsVisible(e.Location)) continue; 64 if(path == selected) return; 65 66 using(var g = CreateGraphics()) 67 { 68 g.DrawPath(Pens.Blue, selected); 69 selected = path; 70 g.DrawPath(Pens.Red, selected); 71 } 72 return; 73 } 74 75 using(var g = CreateGraphics()) 76 { 77 g.DrawPath(Pens.Blue, selected); 78 } 79 80 selected = new GraphicsPath(); // 選択なし nullチェックが面倒なのでカラのパス 81 } 82 83 protected override void OnPaint(PaintEventArgs e) 84 { 85 base.OnPaint(e); 86 87 foreach(var path in paths) 88 { 89 e.Graphics.DrawPath(Pens.Blue, path); 90 } 91 } 92 } 93}
投稿2020/05/11 10:54
編集2023/07/21 13:57総合スコア9862
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/05/12 01:12
お疲れ様です。
回答ありがとうございます。
自分なりにいじって表示させることが出来たんですが塗りつぶしなしの場合はどのように書くのでしょうか?
2020/05/12 09:19
やはりそうきましたか^^;
WinFormsのコントロールは完全な透過性はサポートしていません。
透過部分を親に描画させることで透明に見せていますので、重なったコントロールの描画がされません。
ですのでこの方式ではDrawRectangle相当はできません(何か手があるかもしれませんが、私はわかりません)
ではなんなので、雑な自前描画版を追記しました。
重なり順を考慮していないので、パネル版と比べると選択心地がいまいちです(スマートな方法が思いつきませんでした)
2020/05/14 00:06
お疲れ様です。
ありがとうございました。
なんとかできました。
またよろしくお願いいたします。
0
- 描いた図形情報を保持するクラスを作成し、位置、サイズ、色 などを記憶
- フォームのMouseMoveイベントで、マウス位置が記憶している図形情報と接触しているかどうか判定
- 接触している図形情報の色を変更
- 図形情報を元に、図形を再描画
でどうでしょう。
投稿2020/05/11 07:17
編集2020/05/11 07:18退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。