Tyler Coleman
Tyler Coleman

Reputation: 11

Simple GUI Inputbox PowerShell

I saw some code on an older Stack Overflow on how to accomplish a GUI based input box found below which works great. But I am wondering if there is a way to restrict this to just int's as I am requesting a UPC. And if I can add a simple dropdown list. Not sure if this is possible or not or it I need to use read-line which is quite a bit of code for some simple inputs.

#Ask for UPC
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')

$title = 'Enter UPC'
$msg   = 'Enter the UPC of the Item:'

$upc = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)

Upvotes: 0

Views: 5991

Answers (1)

FoxDeploy
FoxDeploy

Reputation: 13537

If you run this command, you'll see the options we have available for configuring a VisualBasic Input box.

[Microsoft.VisualBasic.Interaction]::InputBox

OverloadDefinitions                                                                              
-------------------                                                                              
string InputBox(string Prompt, string Title, string DefaultResponse, int XPos, int YPos)  
                                                                                                 

So as you can see, we can only configure the prompt, title, default value in the text box and where on the screen it should appear.

However, if instead of using Visual Basic in PowerShell, you were to make your own GUI using WPF which also works in PowerShell, you can restrict the input.

How to do it in WPF

Here's a working form that displays a textbox in WPF.

$inputXML = @"
<Window x:Class="FoxDeploy.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:Azure" 
    mc:Ignorable="d" 
    Title="FoxDeploy Awesome GUI" Height="350" Width="600">    
    <Grid Margin="0,0,45,0">        
        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Height="100" Margin="174,28,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="282" FontSize="16"><Run Text="Use this tool to find out all sorts of useful disk information, and also to get rich input from your scripts and tools"/><InlineUIContainer>
                <TextBlock x:Name="textBlock1" TextWrapping="Wrap" Text="TextBlock"/>
            </InlineUIContainer></TextBlock>
        <Button x:Name="button" Content="OK" HorizontalAlignment="Left" Height="55" Margin="370,235,0,0" VerticalAlignment="Top" Width="102" FontSize="18.667"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="35" Margin="221,166,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="168" FontSize="16"/>
        <Label x:Name="label" Content="UPC" HorizontalAlignment="Left" Height="46" Margin="56,162,0,0" VerticalAlignment="Top" Width="138" FontSize="16"/>
</Grid>
</Window>
"@

$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML
 
$reader=(New-Object System.Xml.XmlNodeReader $xaml)
try{
    $Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch{
    Write-Warning "Unable to parse XML, with error: $($Error[0])`n Ensure that there are NO SelectionChanged or TextChanged properties in your textboxes (PowerShell cannot process them)"
    throw
}
 
#===========================================================================
# Load XAML Objects In PowerShell
#===========================================================================
  
$xaml.SelectNodes("//*[@Name]") | %{"trying item $($_.Name)";
    try {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop}
    catch{throw}
    }

$Form.ShowDialog()

Then, you can add a simple event handler to remove any integers as soon as someone types or pastes them, which looks like this.


$WPFtextBox.add_TextChanged({
    #rPrevious, would prohibit INTs
    #$WPFtextBox.Text = $WPFtextBox.Text -replace '[^0-9a-zA-Z-]',''

    #new, only allows ints
     $WPFtextBox.Text = $WPFtextBox.Text -replace '[^0-9-]',''
})

enter image description here

Accessing the value

Afterwards, when the user closes the window, you can retrieve the last value of the text box in the same way we setup the event handler, by using the $WpfTextbox.Text property.

PS> $WPFtextBox.Text
232123455212

If you want to learn more about these kinds of tools, you can check the guides I wrote or google for 'PowerShell WPF GUI tutorial'

Upvotes: 4

Related Questions