Neat idea! One small problem, if you are near the bottom of the edit window the list can't be fully seen.
What if we put the listbox in a context menu and show that instead?
This is what I tried so far, Note: Add a ContextMenuStrip, named "ContextMenuStrip1".
Code:
Public Class frmmain
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Add some examples to listbox.
With LstFunc.Items
.Add("TestSomeLongWords")
.Add("BackColor")
.Add("Top")
.Add("Left")
.Add("Right")
.Add("Bottom")
.Add("Height")
.Add("Width")
End With
' setup listbox
LstFunc.IntegralHeight = False
LstFunc.Font = New Font("Courier New", 10, FontStyle.Regular)
LstFunc.ScrollAlwaysVisible = True
' Determine size of widest string in listbox
Dim wideString, hzSize As Integer
Using g As System.Drawing.Graphics = LstFunc.CreateGraphics()
For i As Integer = 0 To LstFunc.Items.Count - 1
hzSize = g.MeasureString(LstFunc.Items(i).ToString(), LstFunc.Font).Width
If hzSize > wideString Then
wideString = hzSize
End If
Next
End Using
' get vert scrollbar width
Dim scrollBarWidth As Integer = SystemInformation.VerticalScrollBarWidth
' set listbox size & max size
LstFunc.Size = New Size(wideString + scrollBarWidth, 112)
LstFunc.MaximumSize = LstFunc.Size
' setup ContextMenuStrip, add listbox.
ContextMenuStrip1.AutoSize = False
ContextMenuStrip1.ShowImageMargin = False
ContextMenuStrip1.BackColor = LstFunc.BackColor
ContextMenuStrip1.TabStop = True
ContextMenuStrip1.Size = New Size(LstFunc.Width + 4, LstFunc.Height + 4)
ContextMenuStrip1.Items.Add(New ToolStripControlHost(LstFunc))
ContextMenuStrip1.Show()
LstFunc.Location = New Point(2, 2)
ContextMenuStrip1.Close()
End Sub
Private Sub InsertText()
'Inset text from listbox
txtEditor.SelectedText = LstFunc.Text
'close MenuStrip
ContextMenuStrip1.Close()
'Set focus on editor.
txtEditor.Focus()
End Sub
Private Sub txtEditor_PreviewKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PreviewKeyDownEventArgs) Handles txtEditor.PreviewKeyDown
If (e.KeyCode = Keys.OemPeriod) Then
'Get char position were we need to show listbox.
Dim Po = txtEditor.GetPositionFromCharIndex(txtEditor.SelectionStart)
'Mod below if needed.
Po.Y += (txtEditor.Font.GetHeight() * 2) + 8
Po.X += 30
'Select first item.
LstFunc.SelectedIndex = 0
'Show/Position ContextMenu
ContextMenuStrip1.Show(PointToScreen(Po))
'Set focus on listbox.
LstFunc.Focus()
End If
End Sub
Private Sub LstFunc_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles LstFunc.DoubleClick
'Insert text from listbox to editor.
InsertText()
End Sub
Private Sub LstFunc_KeyUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles LstFunc.KeyUp
'Insert text from listbox to editor on enter or spacebar.
If (e.KeyCode = Keys.Enter) OrElse (e.KeyCode = Keys.Space) Then
InsertText()
' hide on TAB or escape keys
ElseIf (e.KeyCode = Keys.Escape) OrElse (e.KeyCode = Keys.Tab) Then
'close MenuStrip
ContextMenuStrip1.Close()
'Set focus on editor.
txtEditor.Focus()
End If
End Sub
End Class
EDIT: One odd thing is if I press TAB when menu is shown the listbox moves to the right?
EDIT #2: Setting "ContextMenuStrip1.TabStop = True" fixed above problem.