2008年5月1日木曜日

HitTest?

以前のエントリでHitTestを利用して、セルをクリックした際のフォーカス制御を直感的にしたい、というのを書き始めていたけど、見事にすっかり忘れていたので改めて追記~。

目的から考えると必要になるのは、クリックした際のマウス座標なんだよね。で、これを扱うのがHitTestと呼ばれるクラス。例えば次のようなロジックにすると、クリックした座標が取得できたりする。

Dim grdhitTest As HitTestInfo = Me.HitTest(e.X, e.Y)


引数で渡しているものとかで、なんとなく想像がつくとおり基本的にはマウス系のイベントで利用するのが多いかな?

その手のイベントではイベント引数でマウス座標が渡ってくるので、それを用いてHitTestを取得することになるんだよね。



で、この情報をDataGridViewでホストしているユーザーコントロール、今までの話でいったらMultiLayoutControlへと渡してあげるってのが第一段階だと思う。

あとは渡されたコントロール側で、その座標の直下に存在するコントロールを洗い出し、そのコントロールへフォーカスを設定してあげれば当初の目標は達成できるかな。


洗い出すためのやりかたは、渡された座標がコントロールの領域に含まれるか、という判断になるね。



''' <summary>指定した座標の下に存在するコントロールを取得します</summary>

Private Function GetChildControlInContainer(ByVal owner As System.Windows.Forms.Control, ByVal pt As System.Drawing.Point) As System.Windows.Forms.Control
  For Each child As System.Windows.Forms.Control In owner.Controls

    If child.HasChildren Then

      Dim result As System.Windows.Forms.Control = Me.GetChildControlInContainer(child, pt)

      If result IsNot Nothing Then Return result

    End If

    If Not Me._focusControl.IsEditableControlType(child) Then Continue For
#160;   Dim childRect As System.Drawing.Rectangle = _

      New System.Drawing.Rectangle(child.Left, child.Top, child.Width, child.Height)

    If childRect.Contains(pt.X, pt.Y) Then Return child

  Next 
  Return Nothing
End Function



こんな感じでやってあげれば、あとは見つかったコントロールにフォーカスを移動してあげればOK。

ちょっと記憶が薄いんだけど、FrameWorkで用意されているメソッドを利用するやり方もあるんだけど、そのコントロール自体が表示されている状態でなければうまいこといかないってのがあったんで、自前でこういった処理を用意した・・・ハズw

0 件のコメント:

コメントを投稿