Adding Autocomplete to your Textbox forms in PowerShell

Today I had a fun little challenge come-up: how do I go about adding Auto-completion records to my forms?

Turns out it is pretty easy! Let’s start very simply. The following will draw out a small box with an OK button, a textbox, and…thats it. Hitting OK will pass along the output of the box.

#Load the assemblies needed for drawing forms with PowerShell
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 

#region to draw the background form
$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Autocompletion Tool"
$Form.Size = New-Object System.Drawing.Size(300,140)
$Form.StartPosition = "CenterScreen"
$Form.KeyPreview = $True
$Form.MaximumSize = $Form.Size
$Form.MinimumSize = $Form.Size

#begin to draw text box
$textbox = New-Object System.Windows.Forms.TextBox
$textbox.Location = New-Object System.Drawing.Size(10,40)
$textbox.Size = New-Object System.Drawing.Size(200,20)
$textbox.Height = 80
$textbox.Name = 'TextBox_UserName'

$Form.Controls.Add($textbox)

#begin to draw an OK button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(220,38)
$OKButton.Size = New-Object System.Drawing.Size(40,25)
$OKButton.Text = "OK"
$OKButton.Add_Click({$xdept=$ListBox.SelectedItem;$xname=$TextBox.Text;$xfname=$TextBoxfName.Text;$Form.Close()})
$Form.Controls.Add($OKButton)

#Make our form topmost, then show it
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

#Return the value
$textbox.Text

There we go, basic-basic.

autocomplete_01

The difference is simply adding the following lines starting on line 20:

$textbox.AutoCompleteSource = 'CustomSource'
$textbox.AutoCompleteMode='SuggestAppend'
$textbox.AutoCompleteCustomSource=$autocomplete

And with that, you can now directly add entries to the AutoCompleteCustomSource using it’s method .AddRange()

autocomplete_02

You could Import from a file

#Importing from a file
Get-content 'C:\TEMP\User Records.txt' | % {$textbox.AutoCompleteCustomSource.AddRange($_) }

Or you could add individual entries, or the output of a script

#Adding single entries to the inherited AutoCompleteSource object of the textbox
"1","blam","foxdeploy","stephen.owen" | % {$textbox.AutoCompleteCustomSource.AddRange($_) }
autocomplete_03
Voila, Magnifique!

As always, feel free to modify for your own purposes, and I hope that this helps you in the future.

Advertisements

8 thoughts on “Adding Autocomplete to your Textbox forms in PowerShell

  1. Nicola April 23, 2015 / 4:31 am

    Hi i have tryed your code but don’t seems to work… this is the error that show up

    Error
    Specified cast is not valid.

    See the end of this message for details on invoking
    just-in-time (JIT) debugging instead of this dialog box.

    ************** Exception Text **************
    System.InvalidCastException: Specified cast is not valid.
    at System.Windows.Forms.UnsafeNativeMethods.CoCreateInstance(Guid& clsid, Object punkOuter, Int32 context, Guid& iid)
    at System.Windows.Forms.StringSource..ctor(String[] strings)
    at System.Windows.Forms.TextBox.SetAutoComplete(Boolean reset)
    at System.Windows.Forms.TextBox.OnHandleCreated(EventArgs e)
    at System.Windows.Forms.Control.WmCreate(Message& m)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    ************** Loaded Assemblies **************
    mscorlib
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
    —————————————-
    Microsoft.PowerShell.ConsoleHost
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7600.16385
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.ConsoleHost/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.ConsoleHost.dll
    —————————————-
    System
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
    —————————————-
    System.Management.Automation
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7601.17514
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Management.Automation/1.0.0.0__31bf3856ad364e35/System.Management.Automation.dll
    —————————————-
    Microsoft.PowerShell.Commands.Diagnostics
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7601.17514
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Diagnostics/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Diagnostics.dll
    —————————————-
    System.Core
    Assembly Version: 3.5.0.0
    Win32 Version: 3.5.30729.5420 built by: Win7SP1
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Core/3.5.0.0__b77a5c561934e089/System.Core.dll
    —————————————-
    System.Configuration.Install
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Configuration.Install/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.Install.dll
    —————————————-
    Microsoft.WSMan.Management
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7601.17514
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.WSMan.Management/1.0.0.0__31bf3856ad364e35/Microsoft.WSMan.Management.dll
    —————————————-
    System.Transactions
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
    CodeBase: file:///C:/Windows/assembly/GAC_64/System.Transactions/2.0.0.0__b77a5c561934e089/System.Transactions.dll
    —————————————-
    Microsoft.PowerShell.Commands.Utility
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7601.17514
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Utility/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Utility.dll
    —————————————-
    Microsoft.PowerShell.Commands.Management
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7601.17514
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Commands.Management/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Commands.Management.dll
    —————————————-
    Microsoft.PowerShell.Security
    Assembly Version: 1.0.0.0
    Win32 Version: 6.1.7601.17514
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Microsoft.PowerShell.Security/1.0.0.0__31bf3856ad364e35/Microsoft.PowerShell.Security.dll
    —————————————-
    System.Xml
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
    —————————————-
    System.Management
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Management/2.0.0.0__b03f5f7f11d50a3a/System.Management.dll
    —————————————-
    System.DirectoryServices
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.DirectoryServices/2.0.0.0__b03f5f7f11d50a3a/System.DirectoryServices.dll
    —————————————-
    System.Data
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_64/System.Data/2.0.0.0__b77a5c561934e089/System.Data.dll
    —————————————-
    System.Drawing
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
    —————————————-
    System.Windows.Forms
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
    —————————————-
    Accessibility
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.4927 (NetFXspW7.050727-4900)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/Accessibility/2.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
    —————————————-

    ************** JIT Debugging **************
    To enable just-in-time (JIT) debugging, the .config file for this
    application or computer (machine.config) must have the
    jitDebugging value set in the system.windows.forms section.
    The application must also be compiled with debugging
    enabled.

    For example:

    When JIT debugging is enabled, any unhandled exception
    will be sent to the JIT debugger registered on the computer
    rather than be handled by this dialog box.

    • FoxDeploy April 23, 2015 / 8:59 am

      Please post the line in question with the cast that threw this error.

  2. MKANET2 August 19, 2015 / 4:46 pm

    The above error is caused by Powershell running in Multi-threaded Apartment mode (Powershell 2.0 default). So, all Powershell 2.0 users will get this error message; unless they start Powershell with -sta parameter.

  3. HM October 21, 2015 / 6:21 am

    Works great! Thank you!

  4. faheem November 24, 2015 / 2:37 am

    Hi, my code shows an error that AutoCompleteSource, AutoCompleteMode and AutoCompleteCustomSource are not recognized methods but ” $WPFtextbox.Text = ‘One’ ” works ok.

    $xaml.SelectNodes(“//*[@Name]”) | %{Set-Variable -Name “WPF$($_.Name)” -Value $Form.FindName($_.Name)}

    $WPFtextbox.AutoCompleteSource = ‘CustomSource’
    $WPFtextbox.AutoCompleteMode=’SuggestAppend’
    $WPFtextbox.AutoCompleteCustomSource.AddRange(‘One’ ‘Two’, ‘Three’)

  5. James A. Wall May 19, 2016 / 8:28 am

    This is it. I don’t know How I didn’t stumble accross this! Would be perfect if I could query directly from the database. I don’t really understand how to input this into the XAML of my gui script.

    $adOpenStatic = 3
    $adLockOptimistic = 3
    $objConnection = New-Object -comobject ADODB.Connection
    $objRecordset = New-Object -comobject ADODB.Recordset
    $objConnection.Open(“Provider=Microsoft.ACE.OLEDB.12.0; Data Source = c:\Database\Gen3Data.mdb”)
    $objRecordset.Open(“Select Truck_ID from Trucks”, $objConnection,$adOpenStatic,$adLockOptimistic)

    $Mytrucks = $objRecordset.GetRows()
    $objRecordset.Close()
    $objConnection.Close()
    $comboitems = @()
    foreach($trck in $Mytrucks){$comboitems += $trck}

    $comboitems | Out-File C:\Database\trucks.txt

    It would be perfect if I could go direct to the DB instead of the text file. And obviously I have no idea, ( start to toy with it now) on how to put that box into my GUI script I already Built. Dude your a genius!

    • FoxDeploy May 19, 2016 / 10:32 am

      I’m not a genius just stubborn.

      You don’t add this to your xaml. Put this at the bottom third of your script into the ‘make the functions work section’ as it’s called in the template.

      Then, in the line where you do an out-file, instead use the command to add that to the autocomplete dictionary.

      • James A. Wall May 19, 2016 / 11:35 am

        I am not able to build the auto complete box.

        You cannot call a method on a null-valued expression.
        At C:\Users\office1\Documents\GitHub\JWallCreations\AsphaultQueue\Gui.ps1:127 char:44
        + Get-content ‘C:\Database\trucks.txt’ | % {$textbox.AutoCompleteCustomSource.Add …
        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : InvokeMethodOnNull

Have a code issue? Share your code by going to Gist.github.com and pasting your code there, then post the link here!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s