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

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

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

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

Q&A

1回答

6731閲覧

visualstudioを用いたc#においての矩形の移動について

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

0グッド

0クリップ

投稿2017/04/11 07:55

###前提・実現したいこと

マウスで選択した箇所のみの矩形の移動

###発生している問題・エラーメッセージ

マウスを矩形の上に乗せると色が変わる仕様にしたのですが その色が変わった部分の移動方法が分かりません。

###該当のソースコード

c#

1【Form.cs】 2 3using System; 4using System.Collections.Generic; 5using System.ComponentModel; 6using System.Data; 7using System.Drawing; 8using System.Linq; 9using System.Text; 10using System.Threading.Tasks; 11using System.Windows.Forms; 12 13namespace test20form02 14{ 15 public partial class Form1 : Form 16 { 17 /// <summary> 18 /// コンストラクター 19 /// </summary> 20 public Form1() 21 { 22 InitializeComponent(); 23 this.pen = new Pen(Color.Blue); 24 this.spen = new Pen(Color.Red); 25 this.recIter = new RecObjIterator(); 26 } 27 28 //ペンオブジェクト 29 Pen spen; 30 Pen pen; 31 32 //矩形オブジェクトのイテレータ(集合・グループ)クラス 33 private RecObjIterator recIter; 34 35 /// <summary> 36 /// フォームイベントハンドラー 37 /// </summary> 38 /// <param name="sender"></param> 39 /// <param name="e"></param> 40 private void Form1_Load(object sender, EventArgs e) 41 { 42 //矩形オブジェクトを100個生成する 43 this.recIter.init(100); 44 45 } 46 47 /// <summary> 48 /// ボタンクリックイベントハンドラー 49 /// </summary> 50 /// <param name="sender"></param> 51 /// <param name="e"></param> 52 private void button1_Click(object sender, EventArgs e) 53 { 54 this.Close(); 55 } 56 57 /// <summary>/ 58 /// ピクチャーボックス ペイントイベントハンドラー 59 /// 矩形を表示する 60 /// </summary> 61 /// <param name="sender"></param> 62 /// <param name="e"></param> 63 private void pictureBox1_Paint(object sender, PaintEventArgs e) 64 { 65 //矩形を表示する 66 this.recIter.Draw(e.Graphics, this.spen, this.pen); 67 } 68 69 /// <summary> 70 /// ピクチャーボックス マウスムーブイベントハンドラー 71 /// </summary> 72 /// <param name="sender"></param> 73 /// <param name="e"></param> 74 private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 75 { 76 //マウス座標を取得 77 var mymouse = new Point(e.X, e.Y); 78 //全矩形の選択状態を解除 79 this.recIter.UnSelectObj(); 80 81 //マウス座標で矩形を選択する 82 this.recIter.SelectByMouse(mymouse); 83 84 //ピクチャーボックスの再表示を依頼する 85 this.pictureBox1.Invalidate(); 86 } 87 88 89 }//class 90}//namespace 91 92 93【RecObj.cs】 94 95using System; 96using System.Collections.Generic; 97using System.Linq; 98using System.Text; 99using System.Threading.Tasks; 100using System.Drawing; 101 102namespace test20form02 103{ 104 /// <summary> 105 /// 矩形オブジェクトの管理クラス 106 /// </summary> 107 class RecObj 108 { 109 /// <summary> 110 /// プロパティ 111 /// 矩形オブジェクト 112 /// </summary> 113 public Rectangle Rec 114 { 115 set { this.rec = value; } 116 get { return this.rec; } 117 118 } 119 120 /// <summary> 121 /// プロパティ 122 /// 選択されているかどうか 123 /// </summary> 124 public bool isSelect 125 { 126 set { this.isselect = value; } 127 get { return this.isselect; } 128 } 129 /// <summary> 130 /// コンストラクター 131 /// </summary> 132 public RecObj() 133 { 134 this.isselect = false; 135 this.rec = new Rectangle(); 136 } 137 138 //選択されているかどうか 139 private bool isselect; 140 //矩形オブジェクト 141 private Rectangle rec; 142 143 /// <summary> 144 /// 選択フラグに設定する 145 /// </summary> 146 public void SetisSelect(bool flg) 147 { 148 this.isselect = flg; 149 } 150 151 /// <summary> 152 /// オブジェクトの移動 座標の書き換え 153 /// </summary> 154 /// <param name="from">前のマウス座標</param> 155 /// <param name="to">今のマウス座標</param> 156 public void Move(Point from, Point to) 157 { 158 var x = to.X - from.X; 159 var y = to.Y - from.Y; 160 161 rec.X = rec.X + x; 162 rec.Y = rec.Y + y; 163 } 164 165 /// <summary> 166 /// 指定されたグラフィックオブジェクトに矩形を描画する 167 /// </summary> 168 public void Draw(Graphics gra, Pen pen, Pen pen2) 169 { 170 Pen mypen = null; 171 if (this.isSelect) 172 { 173 mypen = pen; 174 } 175 else 176 { 177 mypen = pen2; 178 } 179 gra.DrawRectangle(mypen, this.rec); 180 } 181 } 182} 183 184 185【RecObjIterator.cs】 186 187using System; 188using System.Collections.Generic; 189using System.Linq; 190using System.Text; 191using System.Threading.Tasks; 192using System.Drawing; 193 194namespace test20form02 195{ 196 /// <summary> 197 /// 矩形オブジェクトの集合を処理するクラス 198 /// </summary> 199 class RecObjIterator 200 { 201 /// <summary> 202 /// プロパティ 203 /// 矩形オブジェクトリストを参照 204 /// </summary> 205 public List<RecObj> Recs 206 { 207 get { return this.recs; } 208 } 209 210 /// <summary> 211 /// コンストラクター 212 /// </summary> 213 public RecObjIterator() 214 { 215 this.recs = new List<RecObj>(); 216 } 217 218 //矩形オブジェクトのグループ 219 private List<RecObj> recs; 220 221 222 /// <summary> 223 /// 矩形オブジェクトを生成する 224 /// </summary> 225 /// <param name="num"></param> 226 public void init(int num) 227 { 228 for (int i = 0; i < num; i++) 229 { 230 var myrec = new RecObj(); 231 myrec.Rec = new Rectangle(10 + (i * 2), 10 + (i * 2), 100, 100); 232 this.recs.Add(myrec); 233 } 234 } 235 236 /// <summary> 237 /// 矩形オブジェクトを追加する 238 /// </summary> 239 /// <param name="rec"></param> 240 public void Add(RecObj rec) 241 { 242 this.recs.Add(rec); 243 } 244 245 /// <summary> 246 /// 矩形オブジェクトのリストの選択状態を解除 247 /// </summary> 248 public void UnSelectObj() 249 { 250 foreach (var myobj in this.recs) 251 { 252 myobj.isSelect = false; 253 } 254 } 255 256 /// <summary> 257 /// マウス座標で矩形オブジェクトのリストを選択 258 /// </summary> 259 /// <param name="mouse"></param> 260 public void SelectByMouse(Point mouse) 261 { 262 foreach (var myobj in this.recs) 263 { 264 if (myobj.Rec.Contains(mouse) == true) 265 { 266 myobj.isSelect = true; 267 } 268 } 269 270 } 271 272 /// <summary> 273 /// 指定されたグラフィック(キャンバス)に指定のペンで矩形を表示する 274 /// </summary> 275 /// <param name="gra"></param> 276 /// <param name="pen"></param> 277 /// <param name="pen2"></param> 278 public void Draw(Graphics gra, Pen pen, Pen pen2) 279 { 280 foreach (var myobj in this.recs) 281 { 282 myobj.Draw(gra, pen, pen2); 283 } 284 } 285 } 286} 287

###補足情報(言語/FW/ツール等のバージョンなど)
visualstudio2013

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

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

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

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

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

Zuishin

2017/04/11 08:46

どのように移動させるんですか? 色が変わった瞬間にランダムに動くのですか?
退会済みユーザー

退会済みユーザー

2017/04/11 09:50 編集

矩形の上にマウスポインタを乗せるとマウスポインタが乗っている箇所が赤色に変化するのですが、その赤色に変化した箇所のみを好きな座標へ移動させたいと考えております.
ozwk

2017/04/12 05:03 編集

赤色の部分を好きな座標にどうやって移動させたいんですか?マウスドラッグ?予め座標何処かに書いておいてクリックした瞬間ワープ?
退会済みユーザー

退会済みユーザー

2017/04/12 05:24

ozwkさん 矩形の上にマウスポインタを合わせて赤色に変化した箇所をmousedownしているあいだピクチャーボックス内で好きな個所に移動させて、mouseupで好きな個所に置きたいです。座標はあらかじめ指定するわけではなく置きたい箇所に置けるようにしたいです。よろしくお願いします。
Zuishin

2017/04/12 05:27

haru666 さんの回答がそのものずばりだと思いますが。
退会済みユーザー

退会済みユーザー

2017/04/12 05:32

zuishinさん そうなのですが、Moveの実装がなかなかうまくいかず困っている状態です。。
Zuishin

2017/04/12 05:57

マウスダウンされた時点で、矩形とカーソル位置の座標を求めます。マウスが動いた時点でその位置関係が等しくなるように動かせばいいんじゃないですか? 仮に矩形の左上が (100, 100) マウスが (110, 110) だったとすると、 マウスが (200, 200) に動いたときに矩形を (190, 190) に動かせばいいと思います。
Zuishin

2017/04/13 00:01

えっ? 退会? 質問しておいて、完成品のコード貼ってもらえなかったら退会?
guest

回答1

0

namespaceにtest20と書いてあるのでヒント形式で回答していきたいと思います。

色が変わった部分の移動方法が分かりません。

というのでは移動の開始方法が分からないので、前提としてマウスをクリックしてる間移動するという想定でお話します。


①RecObjIteratorにMoveを実装する
複数選択できるわけですから、纏めて移動できるように拡張しましょう。

以下のようなメソッドを追加してください。

void MoveSelected(Point from, Point to) { // 選択されている矩形のMoveを呼び出す }

②矩形の移動開始地点を取得する
矩形がどこから移動を始めたのか記憶しなければいけません。
マウスがクリックされた時から移動が始まるならクリック位置が始点になります。

マウスのクリックが開始されたのを知るにはOnMouseDownイベントを使います。
マウスの移動の検知にはOnMouseMoveイベントを使います。
マウスのクリックが終了したのを知るにはOnMouseUpイベントを使います。

フォームにマウスの座標を記憶するための変数を追加してください。

以下ができていれば良いですね。

OnMouseDown ->MouseEventArgsから最初の座標を得る 矩形を移動する状態にする OnMouseMove ->矩形を移動する状態なら、MouseEventArgsから現在の座標を得る 1回前の座標と組み合わせて矩形を移動する(※RecObjIterator.MoveSelectedを使う) 現在の座標を記憶する OnMouseUp ->MouseEventArgsから現在の座標を得る 1回前の座標と異なれば、矩形を移動する(※必要ならRecObjIterator.MoveSelectedを使う) 矩形を移動する状態を終了する

※余談ですが、マウス移動時になめらかに矩形を移動させるにはPictureBoxコントロールのCaptureプロパティをtrueにします。OnMouseDownでtrueにし、OnMouseUpでfalseにすると良いのですが、これがどういう意味かは自分で調べてみてください。


③選択された矩形を維持する
今のままだとMouseMoveが呼ばれるたびに選択される図形が変わってしまいますね。
座標の移動時にもMouseMoveイベントを経由する必要があります。
マウスがクリックされている間は同じ図形を全て移動したいのですよね。
であれば、クリックされている間は今の処理が再度呼び出されないようにする必要があります。

private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (/* 矩形が移動中なら */) { // ここに移動用の処理を書く // 過去の処理で選択状態が作られているわけだから // 選択された矩形のMoveを呼び出せばよい } else { // 今までの処理... //マウス座標を取得 var mymouse = new Point(e.X, e.Y); //全矩形の選択状態を解除 this.recIter.UnSelectObj(); //マウス座標で矩形を選択する this.recIter.SelectByMouse(mymouse); //ピクチャーボックスの再表示を依頼する this.pictureBox1.Invalidate(); } }

投稿2017/04/11 08:53

編集2017/04/12 04:58
haru666

総合スコア1591

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問