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

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

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

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

Q&A

解決済

2回答

956閲覧

フォームをドラックして移動させる

tarot_shogun

総合スコア29

C#

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

0グッド

0クリップ

投稿2018/02/26 11:22

「作って覚えるVisualC#2017デスクトップアプリ入門」という書籍を使って学習をしています。

書籍中にマウスでフォームをドラックし移動させるプログラムがありました。

C#

1 // テキストボックスをマウスでクリックしたとき 2 private void FormFusen_MouseDown(object sender, MouseEventArgs e) 3 { 4 if(e.Button == MouseButtons.Left) 5 { 6 this.mouseX = e.X; 7 this.mouseY = e.Y; 8 } 9 } 10 11 // テキストボックスでクリックしたマウスを移動させたとき 12 private void FormFusen_MouseMove(object sender, MouseEventArgs e) 13 { 14 if(e.Button == MouseButtons.Left) 15 { 16 this.Left += e.X - mouseX; 17 this.Top += e.Y - mouseY; 18 } 19 }

私はこのプログラムを以下のように編集しても動くのではないかと考えました。

C#

1 // 省略 2 // テキストボックスでクリックしたマウスを移動させたとき 3 private void FormFusen_MouseMove(object sender, MouseEventArgs e) 4 { 5 if(e.Button == MouseButtons.Left) 6 { 7 this.Left = e.X; 8 this.Top = e.Y; 9 } 10 }

ところが、編集後のプログラムを動かすと、
ウィンドウが反復横跳びをするように動き回り、マウス位置にフォームが移動しません。

テキストのおかげで上のプログラムの仕組みは分かりました。
しかし、なぜ編集後のプログラムが変な挙動になってしまうのかが分かりません。

乱雑な質問で分かりにくいかとは思いますが、
もし分かるようでしたら、回答のほど宜しくおねがいます。

https://books.google.co.jp/books?id=zPlFDwAAQBAJ&pg=PA208&lpg=PA208&dq=this.Left+%3D+e.X;&source=bl&ots=BxT0tTgdSQ&sig=lm2OWg3ENUztudWUJEuoGLUF7vE&hl=ja&sa=X&ved=0ahUKEwj97q39rcPZAhVHJpQKHbEwBdAQ6AEILjAB#v=onepage&q=this.Left%20%3D%20e.X%3B&f=false)

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

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

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

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

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

guest

回答2

0

書籍の例はグローバル座標にしてから計算するとかもうちょっとわかりやすい例があるように思うのですが、、、

それはさておき、talot_shogunさんの変更はテキストボックスの左上からカーソルまで距離をフォームの位置(画面左上からの距離)に設定しているので、そもそもの原点が異なりますから予期しない動作になります。

MouseMoveが発生した瞬間(左)とそれによりFormを移動した時(右)を図にするとわかりやすいと思います。
Formの中の四角がテキストボックスで、〇がカーソルの位置、矢印がテキストボックスとカーソルとの距離です。
イメージ説明

1回目のMouseMoveではテキストボックスの原点とカーソルの距離は小さいので、
フォームは画面の左上に移動します。
そうするとカーソルとテキストボックスが離れてしまうので、2回目のMouseMoveでは距離が大きくなりフォームは画面の右下方向に移動します。
するとすると次はテキストボックスとカーソルが近づくので、3回目のMouseMoveでは距離が小さくなるのでフォームは画面の左上に移動して、、、というのを繰り返しているため反復動作になります。

投稿2018/02/26 13:35

toki_td

総合スコア2850

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

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

tarot_shogun

2018/02/27 02:55

回答ありがとうございます。 テキストではグローバル座標や座標系について触れられていませんでしたが、 toki_tdさんの図解のおかげで理解することが出来ました。ありがとうございました。
guest

0

ベストアンサー

こんにちは。

座標系の相違の問題です。
フォームのTop, Leftは通常はスクリーン座標系ですので原点は画面の左上です。
そして、FormFusen_MouseMoveで受け取るマウスの座標はFormFusen座標系ですので原点はFormFusenの左上です。その座標系を変換せずに直接設定しているため可笑しくなっているのだと思います。

例えば、フォームが(100, 200)にあり、マウスが(150, 260)の位置にある場合、FormFusen_MouseMoveで伝達されるマウス座標は(50, 60)になります。この状態でフォームを(50, 60)へ移動するとフォームは左上方向に吹っ飛びます。
ふっとんだ後、フォームは(50, 60)の位置にありますから、もしそのままFormFusen_MouseMoveイベントが発生した場合(マウスを動かさないと発生しませんが、簡単のためそのまま発生したと仮定します)、この時マウスは元の(150, 260)にあるので、FormFusen_MouseMoveで伝達されるマウス座標は(100, 200)となります。そして、フォームを(100, 200)へ移動すると、(50, 60)→(100, 200)へ吹っ飛びます。

投稿2018/02/26 13:32

Chironian

総合スコア23272

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

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

tarot_shogun

2018/02/27 02:48 編集

回答ありがとうございます。 座標系の違いがおかしな挙動を引き起こしていたんですね。 分かりやすい解説のおかげで納得しました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問