- PR -

DragイベントをFormで取得したい。

投稿者投稿内容
ガルマ・ザビ
ベテラン
会議室デビュー日: 2007/06/07
投稿数: 55
お住まい・勤務地: ジオン公国
投稿日時: 2007-06-13 09:40
皆様、ご回答ありがとうございます。

私は、皆様がおっしゃることが技術的に「できない」と思ってはいません。
ただDragEnter、DragOver、DragLeave、OnQueryContinueDragなどの処理が走るごとに
すべてのコントロールを走査するのはコストがかかるよなぁと考えているわけです。

こんなことも含めて、検討したいと思います。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2007-06-13 09:51
引用:

ガルマ・ザビさんの書き込み (2007-06-13 09:40) より:

私は、皆様がおっしゃることが技術的に「できない」と思ってはいません。
ただDragEnter、DragOver、DragLeave、OnQueryContinueDragなどの処理が走るごとに
すべてのコントロールを走査するのはコストがかかるよなぁと考えているわけです。


走査する必要がどこにあるの?
ガルマ・ザビ
ベテラン
会議室デビュー日: 2007/06/07
投稿数: 55
お住まい・勤務地: ジオン公国
投稿日時: 2007-06-13 10:19
DragEnterを例にします。

Form→共通のDragEnter処理(処理A)
Panel、Button→共通のDragEnter処理、または、各コントロールに特化した処理(処理B、C)

すべてのDragイベントをFormで受け付けるということは、
どこのコントロールでDragEnterが発生したのかは分からないと思うのですが、、、。

そうなると、処理B、Cを行いたい場合、Zオーダーを考慮して、
マウス位置とコントロールの領域から、DragEnterが発生したコントロールを特定する必要が出てくると思うのです。


私の考えが根本的に間違っていましたら、お導きください。
れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-06-14 05:56
デザイナツールって…
ものすごくめんどくさそうな感じですねぇ。

普通のWindowsアプリの発想で文面を読む限りでは、
Jittaさんの言うように、
普通に各コントロールでDragXXXを受けて、
親コントロールの適当な関数を呼ぶようにすればいいだけだと思いますが。
よくやる手です。

引用:

すべてのコントロールを走査するのはコストがかかるよなぁと考えているわけです



このコストというのは、実行時の時間のことでしょうか?
プログラムにかかる時間のことでしょうか?

親をたどるだけなら、階層に対して比例した時間しかかかりません。
階層はコントロールの数に対してlogで効いてくるはずですので、
親を操作する時間が問題になる前に
コントロールの数が多すぎて重くなる問題にぶち当たるはずです。

こんな感じのコードでどうでしょう?

コード:
Public Class DragTestForm
    Implements IDragTrackable

    Private Sub DragTestForm_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
        'このコントロールにドラッグされた場合の処理
    End Sub

    Public Function ChildDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) As Boolean Implements IDragTrackable.ChildDrag
        '子コントロールがあったらそれから呼ばれる。
        '子コントロールのドラッグを横取りしたい場合はここで処理。
        '処理したらTrue,しなかったらFalseを返す。
        Return False
    End Function

End Class

Public Class DragTrackablePanel
    Inherits Panel
    Implements IDragTrackable

    Private Sub DragTrackablePanel_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
        If CType(Me.Parent, IDragTrackable).ChildDrag(sender, e) Then Exit Sub
        'このコントロールにドラッグされた場合の処理
    End Sub

    Public Function ChildDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) As Boolean Implements IDragTrackable.ChildDrag
        '子コントロールがあったらそれから呼ばれる。
        '子コントロールのドラッグを横取りしたい場合はここで処理。
        '処理したらTrue,しなかったらFalseを返す。
        Return CType(Me.Parent, IDragTrackable).ChildDrag(sender, e)
    End Function

End Class

Public Interface IDragTrackable
    Function ChildDrag(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) As Boolean
End Interface



上記コードではDragDropしか処理してませんが。
親のDragDropイベントを直接Raiseするとか
親のDragDropイベントハンドラを直に呼ぶとかもありますが、
どうせやるならこれが一番きれい。

ドラッグされたコントロールを親のコントロールから特定したいときは
senderでわかるし、
ZオーダーはWindowsが判断してくれる。
コントロールを動的に追加しても、
IDragTrackableを実装してれば問題は発生しない。

大佐のご要望には適っているように見えます。

ただ。
デザイナツール作ってるという話なので、よくわかりません。
ドラッグドロップコードを含めてシリアル可したいとか
だったらぜんぜん見当違いですし、
コントロールの継承ができないとかでもアウト。

どーしてもフックしたいとなると…
やりたくないですねぇ。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-06-14 07:29
ごめん、反対だった。
れいさんが書いて下さっていますが、各コントロールは自分の親を知っていますから、親に「やってくれる?」と、投げていけばいいでしょう。。。でした。
_________________
ガルマ・ザビ
ベテラン
会議室デビュー日: 2007/06/07
投稿数: 55
お住まい・勤務地: ジオン公国
投稿日時: 2007-06-14 13:08
デザイナーツール、面倒くさいですよ(^-^;

れいさん、コードまで書いていただきありがとうございます。
いただいたものも含め、検討させていただきたいと思います。

本当にありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)