C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: コントロールをドラッグ


(過去ログ 136 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■80139 / inTopicNo.1)  コントロールをドラッグで移動中にマウスの別ボタンを押したら
  
□投稿者/ たーぼー (1回)-(2016/06/16(Thu) 00:24:45)

分類:[VB.NET/VB2005 以降] 

2016/06/16(Thu) 00:29:35 編集(投稿者)

開発環境 Microsoft Visual Studio Community 2015
使用言語 VB.Net (Visual Basic 2015)
フレームワーク .NET Framework 4.5.2

OS Windows7 Professional SP1 64bit
CPU Intel(R) Core(TM) i7 CPU 870 @2.93GHz 2.93GHz
RAM 16.0GB


はじめまして、初心者なりに自作アプリを作ろうと、色々な記事を読み漁っています。


まず、私が悩んでいる現象について簡単に述べます。

1.
ラベルをドラッグで移動できるようにしたが、ドラッグ中にマウスの右ボタンや中央ボタンをクリックすると、その後のドラッグ処理が不安定になる。

2.
具体的には、MouseMoveイベントが起こることを期待してマウスカーソルを移動させた際、ある程度の速度でマウスカーソルを移動させると、
マウスカーソルが移動中のラベルから脱出してしまい、Label1.MouseMoveではなく、Label1.MouseLeaveが発生する。

3.
この現象は、余計なことをせず左ボタンのみを押下してドラッグを行っている限りは発生しない。

4.
左ボタンでのドラッグ中に、例えば右ボタンを押して、左右のボタンが同時に押下されている状態のドラッグでも発生しない。

5.
4の後、左ボタンは押下したまま、それ以外のボタンを「離して」、押されているマウスボタンが「左のみ」になった時に発生する。

6.
5の後、再び右ボタンを押下して左右のボタン同時押しに戻すと、発生しなくなる。

7.
「発生していない」場合、ラベルはフォームの外までドラッグで引っ張ることができる。
(見た限り、左ボタンを離さない間は他のあらゆるイベントが無視されている印象)

8.
「発生している」場合、ラベルはフォームの端までしか移動することができない。
また、移動中のラベルが他のコントロールの下に潜り込んだ場合も移動がストップする。


以上になります。
このような挙動、どなたかご説明できる方はいらっしゃいませんでしょうか?


(以下、Form1クラスモジュール内のコード)

Private MouseA As Point'マウスボタン押下時の、マウスポインタの座標を取得
Private LabelA As Point'マウスボタン押下時の、Label1の座標を取得


'ラベル上でマウスの左ボタンが押下された時の処理

Private Sub Label1_MouseDown(sender As Object, e As MouseEventArgs) Handles Label1.MouseDown

If e.Button = MouseButtons.Left Then

MouseA = Cursor.Position
LabelA = sender.location

End If

End Sub


'ラベル上でマウスの左ボタンが押下されたまま、マウスポインタが移動したときの処理

Private Sub Label1_MouseMove(sender As Object, e As MouseEventArgs) Handles Label1.MouseMove

If e.Button = MouseButtons.Left Then

sender.location = LabelA + (Cursor.Position - MouseA)

End If

End Sub



以上、分かり辛くて申し訳ありませんが諸先輩方の知恵をお借りしたく存じます。
何卒ご協力の程、よろしくお願い申し上げます。
引用返信 編集キー/
■80141 / inTopicNo.2)  Re[1]: コントロールをドラッグ
□投稿者/ Azulean (652回)-(2016/06/16(Thu) 05:50:39)
2016/06/16(Thu) 05:51:51 編集(投稿者)

No80139 (たーぼー さん) に返信
> ラベルをドラッグで移動できるようにしたが、ドラッグ中にマウスの右ボタンや中央ボタンをクリックすると、その後のドラッグ処理が不安定になる。
(略)
> 具体的には、MouseMoveイベントが起こることを期待してマウスカーソルを移動させた際、ある程度の速度でマウスカーソルを移動させると、
> マウスカーソルが移動中のラベルから脱出してしまい、Label1.MouseMoveではなく、Label1.MouseLeaveが発生する。

基本的に .NET の Control クラスとその継承クラスは、MouseDown で「マウスキャプチャ」状態に移行し、MouseUp でその状態を解除します。
この「マウスキャプチャ」状態でのみ、コントロールの外に移動しても MouseMove イベントが発生する仕組みになっています。

ただし、この状態は Alt+Tab などによってアクティブなウィンドウが切り替わった場合、他のマウスボタンの MouseUp が発生した場合に途切れる実装になっています。
どうしても継続させたい場合は、MouseCaptureChanged イベントあたりを監視し、ドラッグを継続するべきと判断したら、コントロールの Capture プロパティを True に設定した方が良いでしょう。
(強制的に True にすると、ドラッグを永遠に解除できないので「自分がアクティブである」「マウスボタンが押されたままである」といった判定が必要でしょうね。私の場合は面倒くさいので、MouseCaptureChanged イベントが発生したらドラッグ終了と扱っていますが)
引用返信 編集キー/
■80144 / inTopicNo.3)  Re[2]: コントロールをドラッグ
□投稿者/ たーぼー (2回)-(2016/06/16(Thu) 08:05:11)
No80141 (Azulean さん) に返信

> 基本的に .NET の Control クラスとその継承クラスは、MouseDown で「マウスキャプチャ」状態に移行し、MouseUp でその状態を解除します。
> この「マウスキャプチャ」状態でのみ、コントロールの外に移動しても MouseMove イベントが発生する仕組みになっています。
>
> ただし、この状態は Alt+Tab などによってアクティブなウィンドウが切り替わった場合、他のマウスボタンの MouseUp が発生した場合に途切れる実装になっています。
> どうしても継続させたい場合は、MouseCaptureChanged イベントあたりを監視し、ドラッグを継続するべきと判断したら、コントロールの Capture プロパティを True に設定した方が良いでしょう。
> (強制的に True にすると、ドラッグを永遠に解除できないので「自分がアクティブである」「マウスボタンが押されたままである」といった判定が必要でしょうね。私の場合は面倒くさいので、MouseCaptureChanged イベントが発生したらドラッグ終了と扱っていますが)

早速のご回答ありがとうございます。
Label1.MouseDownイベント時にsender.capture = falseとすることで、初回のドラッグ開始時にも同様の挙動を起こすようになりました。
「発生している」場合の対処方法は自己検討中にほぼ確立できていますので、これで処理方法を統一できるようになりました。

ドラッグしたラベルを別ウィンドウまでドラッグすることも想定していましたので、それもcaptureプロパティのtrueとfalseの使い分けで対処できそうです。

どうもありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -