DOBON.NET DOBON.NETプログラミング掲示板過去ログ

フォーム内にフォームを表示でComboBoxのテキストが編集できない

環境/言語:[VB.NET(2005) vista]
分類:[.NET]

「DOBON.NET プログラミング道」の「フォーム内にフォームを表示する」を基に
した画面をVB2005で作成しています。

フォーム内に表示するフォーム(子フォーム)上にコンボボックス(DropDown)を
配置していますが、実行時にマウスでクリックしてもテキスト部分にカーソルが
移動しません。
タブでフォーカス移動するか、マウスでドロップダウンのリストを表示すると
テキスト入力部分にカーソルが設定され、編集できるようになります。

子フォーム上でも通常の動作をするような解決策はないでしょうか?
私のPCで試したところ、
以下の方法でクリック時に編集可能になりました。
クリック後のキャレット移動はカーソルキーしか使えないため、
通常の動作と全く同じではありませんが、
とりあえず以下のコードで試してみてください。
 
' このFormを別Formの中に表示する
Public Class ComboBoxAndForm
    Inherits Form
    Dim TextBox1 As New TextBox
    Dim WithEvents ComboBox1 As New ComboBox
    Public Sub New()
        Me.Text = Me.GetType.Name
        With Me.TextBox1
            .Location = New Point(100, 30)
        End With
        With Me.ComboBox1
            .Location = New Point(50, 80)
            .DropDownStyle = ComboBoxStyle.DropDown
            .DataSource = New String() {"あああ", "いいい", "ううう", "えええ"}
        End With
        Me.Controls.AddRange(New Control() {Me.TextBox1, Me.ComboBox1})
    End Sub
    Private Sub ComboBox1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ComboBox1.Click
        Me.ComboBox1.Select()
    End Sub
End Class
2009/01/01(Thu) 02:11:06 編集(投稿者)

コードをバージョンアップしてみました。
通常の動作では、ComboBoxのTextが「あいうえお」の場合、
「い」の右半分をクリックすると、「う」にキャレットが移動するようです。
それに合わせて作ってみました。
また、マウスドラッグ時の反転表示も実装しました。
参考になれば幸いです。
 
' このFormを別Formの内部に表示する
Public Class ComboBoxAndForm
    Inherits Form
    Dim TextBox1 As New TextBox
    Dim WithEvents ComboBox1 As New ComboBoxEx
    Public Sub New()
        Me.Text = Me.GetType.Name
        With Me.TextBox1
            .Location = New Point(100, 30)
        End With
        With Me.ComboBox1
            .Location = New Point(50, 80)
            .Width = 200
            .DropDownStyle = ComboBoxStyle.DropDown
            .DataSource = New String() {"あいうえおABCかき", "いいい1", "ううう2", "えええ3"}
        End With
        Me.Controls.AddRange(New Control() {Me.TextBox1, Me.ComboBox1})
    End Sub
End Class
 
' カスタマイズされたComboBox
Public Class ComboBoxEx
    Inherits ComboBox
    ' ↓Mouseドラッグ時の反転表示領域の後端のIndexを保持する変数
    Dim m_selectionend As Integer = 0
    ' ↓Focus取得時のClickなら、True
    Dim m_isfirstclick As Boolean = False
    Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
        If Me.Focused = False Then
            Me.m_isfirstclick = True
            Me.Focus()
        Else
            Me.m_isfirstclick = False
            Me.SelectionStart = Me.HitTest
            Me.SelectionLength = 0
            Me.m_selectionend = Me.SelectionStart
        End If
        MyBase.OnMouseDown(e)
    End Sub
    Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
        If Me.m_isfirstclick = False AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
            Dim ht As Integer = Me.HitTest
            If ht < Me.m_selectionend Then
                Me.SelectionStart = ht
                Me.SelectionLength = Me.m_selectionend - ht
            Else
                Me.SelectionLength = Me.HitTest - Me.SelectionStart
            End If
        End If
        MyBase.OnMouseMove(e)
    End Sub
    ' Clickした文字のIndexを取得する
    Private Function HitTest() As Integer
        Dim p As Point = Me.PointToClient(Cursor.Position)
        ' 各部分文字列の幅を格納するList
        Dim lst As New List(Of Single)
        lst.Add(0)
        Using g As Graphics = Me.CreateGraphics
            For i As Integer = 1 To Me.Text.Length
                Dim ss As String = Me.Text.Substring(0, i)
                Dim sz As SizeF = g.MeasureString(ss, Me.Font)
                lst.Add(sz.Width - Me.Margin.Left) ' ← Me.Margin.Leftを引いているのは、苦し紛れ
            Next
            For i As Integer = 0 To Me.Text.Length - 1
                If p.X <= (lst(i) + lst(i + 1)) / 2 Then
                    ' この文字にヒットした
                    Return i
                End If
            Next
        End Using
        ' ヒットしない場合は、後端のIndexを返す
        Return Me.Text.Length
    End Function
End Class
H.K.R.さん
ありがとうございます。休みで環境がなくて返信が遅れました。
解決しました。
バージョンアップ版も試してみます。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板