質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

1127閲覧

ドラッグしたグラフィックスをコントロールの上を通過させたい。

guijiu

総合スコア35

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/03/15 08:21

以下のソースコードは、フォームForm1の上でマウスクリックすると、下の図のように赤い円が表示され、またその円をドラッグすると、マウスに従って移動します。

イメージ説明

ここで、質問があります。

このドラッグした円を、ラベルやスクロールバーなど、コントロールを横切るとき、その下に隠れてしまいます。
本当は、コントロールの上側を通過させ、円の一部の表示が消えないようにしたいのですが、どのようにすればいいでしょうか。
ご教示の程、よろしくおねがいします。

(なお、ソースコードの中にConsole.WriteLineがありますが、これを表示させるためには、VSのプロジェクト--(プロジェクト名)プロパティ--アプリケーションの中の「出力の種類(U)」リストボックスでコンソールアプリケーションを選択すると表示されます。)

C#

1using System; 2using System.Windows.Forms; 3using System.Drawing; 4using System.Collections.Generic; 5 6namespace MoveObject 7{ 8 class Form1 : Form 9 { 10 const int RADIUS = 20; // 円の半径 11 bool dragFlag = false; // リストに記録された円をドラッグした時のフラグ 12 int index; // ドラッグした既存の円を示すインデックス(添え字) 13 14 Point p = new Point(); // 円の座標をテンポラリに記録 15 private List<Point> ls; // 円を描画する場所(円の中心)を記録するリスト 16 Label label1 = new Label(); // 参考文献を表示するラベル 17 HScrollBar hScrollBar = new HScrollBar(); // スクローブバー(現状では表示だけ) 18 19 public static void Main() 20 { 21 Application.Run(new Form1()); 22 } 23 24 25 public Form1() 26 { 27 this.Text = "円を追加し、またドラッグして動かす"; 28 this.Size = new Size(640, 480); 29 this.Controls.Add(label1); 30 this.Controls.Add(hScrollBar); 31 32 ls = new List<Point>(); // 円の中心を記録するリスト 33 34 this.DoubleBuffered = true; // 円を動かしたときにちらつきを抑えるため 35 36 // イベントハンドラーの登録 37 this.MouseDown += new MouseEventHandler(fm_MouseDown); 38 this.MouseMove += new MouseEventHandler(fm_MouseMove); 39 this.MouseUp += new MouseEventHandler(fm_MouseUp); 40 this.Paint += new PaintEventHandler(fm_Paint); 41 42 label1.MouseMove += new MouseEventHandler(label1_MouseMove); 43 44 45 // 参考文献を表示するラベル 46 label1.BorderStyle = BorderStyle.FixedSingle; 47 label1.Location= new Point(15, 150); 48 //label1.Parent = this; 49 label1.AutoSize = true; 50 label1.Text = "本ソースコードは、ソフトバンククリエーティブ社出版の高橋麻奈著「やさしいC#(第3版)p222他を参考に作成した。"; 51 52 hScrollBar.Location = new Point(15, 200); 53 hScrollBar.Size = new Size(600, 20); 54 55 } 56 57 58 public void fm_MouseDown(Object sender, MouseEventArgs e) 59 { 60 p.X = e.X; 61 p.Y = e.Y; 62 63 if (ls.Count != 0) // リストlsに1つ以上円が登録されているときの処理処理 64 { 65 foreach (Point pointRegisted in ls) 66 { 67 // 既存の円の中でマウスクリックしたことを判定し、処理する。 68 if ((p.X - pointRegisted.X) * (p.X - pointRegisted.X) + (p.Y - pointRegisted.Y) * (p.Y - pointRegisted.Y) < RADIUS * RADIUS) 69 { 70 Console.WriteLine("該当した円の中"); 71 index = ls.IndexOf(pointRegisted); // ドラッグした円のインデックスを記録 72 dragFlag = true; // 円をドラッグしたことを表すフラグを立てる 73 break; 74 } 75 else Console.WriteLine("リスト検索中の円の外"); 76 } 77 78 if (!dragFlag) // リストlsに円がひとつも登録されていない時の処理(初めに円を登録するときの処理) 79 { 80 ls.Add(p); //円を初めて追加 81 } 82 } 83 else 84 { 85 ls.Add(p); // リストに円がひとつ以上あるときに、さらに追加 86 } 87 88 this.Invalidate(); 89 } 90 91 public void label1_MouseMove(Object sender, MouseEventArgs e) 92 { 93 Console.WriteLine("label1上と移動中"); 94 } 95 96 97 public void fm_MouseMove(object sender, MouseEventArgs e) 98 { 99 // 円をドラッグしているときの処理 100 if (dragFlag) 101 { 102 // 円をドラッグしマウスを移動した位置を記録する。 103 p.X = e.X; 104 p.Y = e.Y; 105 ls[index] = p; // indexで示された円の位置を書き換える 106 107 Console.WriteLine("移動中 p.X={0} p.Y={1} ",p.X,p.Y); 108 109 this.Invalidate(); 110 } 111 } 112 113 114 public void fm_MouseUp(object sender, MouseEventArgs e) 115 { 116 if (dragFlag) 117 { 118 p.X = e.X; 119 p.Y = e.Y; 120 ls[index] = p; // マウスドラッグを離した位置に書き換える 121 122 this.Invalidate(); 123 } 124 dragFlag = false; 125 } 126 127 128 // MoveCircleのFormに描画(paint)する 129 public void fm_Paint(object sender, PaintEventArgs e) 130 { 131 Graphics g = e.Graphics; 132 Pen dp = new Pen(Color.Red, 1); 133 134 // 円を順番に描画する 135 foreach (Point p in ls) 136 g.DrawEllipse(dp, p.X - RADIUS, p.Y - RADIUS, RADIUS * 2, RADIUS * 2); 137 } 138 } 139} 140

操作環境:Wid10 
Microsoft Visual Studio Community 2019
Version 16.4.6

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/03/15 08:25

円をフォームに描画するのではなく、円形のコントロールにするのが一番簡単だと思います。その他の手としては、フォームの最全面を透明のコントロールで覆ってそこに描画する方法もありますが、その下のコントロールを扱うのが面倒になります。
guijiu

2020/03/15 08:32

お恥ずかしくお聞きしにくいのですが、「円形のコントロール」とはどのようなことをすればいいのでしょうか? 説明が面倒なようでしたら、参考になるサイトや本をご紹介いただけないでしょうか?
guijiu

2020/03/15 08:38

ありがとうございます。これから食事の支度をしなければならないので、落ち着いたらやってみます。
guijiu

2020/05/06 05:22

Zuishinさん、ご無沙汰しています。返信が遅くなり申し訳ありません。  貴殿の言われるコントロールにするの意味が理解できました。特に円形にはこだわっておらず、Regionは使いませんでした。  成果物として、次のアプリを作ることができました。 https://qiita.com/guijiu/items/226b71957401c08dac09  ご教示いただき、ありがとうございました。
Zuishin

2020/05/06 05:25

自己解決してください。
guest

回答1

0

自己解決

PictureBoxなどのコントロールにイベントハンドラを埋め込むことで、対応できました。

成果物は次のとおりです。

https://qiita.com/guijiu/items/226b71957401c08dac09

投稿2020/05/06 05:27

guijiu

総合スコア35

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問