以前のエントリで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 件のコメント:
コメントを投稿