Eric's Technical Outlet

Learning the hard way so you don't have to

Convert Visual Basic Form to PowerShell

Last Updated: v1.05, May 22, 2015

From time to time, I like to have my PowerShell scripts display a nice GUI. Often, I have a scheduled script with numerous configuration options, and I see no value in forcing any person who uses my scheduled script to have to decipher and retool the options when I can slap together a UI that builds the configuration file for them. That’s just one example of why you might want to have PowerShell generate a GUI. But, this post is not about the philosophy of using a GUI in PowerShell, or using PowerShell instead of a full application development environment. This is about the mechanics.

Of course, there are a number of commercially-available tools that can just pop out a fully-functional PowerShell script to generate a WinForm for you. I personally don’t make enough of these forms to find it worth the money, and for everything else, there are plenty of freely available text editors that suit my tastes well enough. I do create enough that the process of building the form is on the aggravating side, though, especially when I get a form just where I like it and then later decide it needs just a tiny little tweak. So, I built a script to automatically parse the designer.vb file that Visual Basic generates and turn it into PowerShell script.

Script Usage

First, use Visual Basic (any edition, including the Express and Community editions will do) to design your form. The PowerShell script will keep all form and control names, so be sure to set those the way you like. Make sure you save the form.

Locate the automatically generated FORM.designer.vb file. This is what you’ll pass to the ConvertTo-PowerShellForm script as the -SourceFile parameter. If you do nothing else, it will emit the output to the screen in the form of a stand-alone script file. If you paste this output into a .ps1 file and execute it, you should be presented with the same form you designed in VB.

You can also specify DotSourced or Inline for the ScriptType parameter. DotSourced removes the detailed help text and does not automatically show the form. It places a variable for the form in the calling script’s scope, and exposes a Show-FORMNAME function. Inline is similar, except it removes even the short help that DotSourced produces.

If you do not specify the ExcludeAssemblies parameter, the emitted script will include Add-Type lines that automatically add the System.Windows.Forms and System.Drawing namespaces. Without them, the script will not work properly, so if you use this switch, make sure that you call the emitted script from a context that includes those namespaces. There is no known harm in including these assemblies multiple times, so you should always be safe if you leave them in.

New in 1.05: By default, the script now includes a directive to enable visual styles. This will make the form that PowerShell shows more consistent with what you see in Visual Basic’s designer. I’ve never encountered any problems using this, even on Server Core systems. If you don’t want it, specify -DoNotUseVisualStyles. All this does is leave the directive out of the emitted script, it does not actively turn off visual styles.

Finally, you can choose between DestinationScript or ToPipeline. ToPipeline is the default action and doesn’t need to be specified; this passes the script as text to the pipeline. If this script is the final object in the pipeline, the script is displayed on screen. If you use DestinationScript, it writes the output to the file that you specify. If you don’t fully qualify the path, it will assume the local directory that the script is being called from. If you don’t include .ps1 on the end, it will be appended for you. The validation for this parameter isn’t especially bullet-proof, but should suit most uses.

Features of the Emitted Script

The script will expose a Show-FORMNAME function that you can call from other scripts. The form is created as a dialog, as this helps with a great many of the messy issues that could occur from showing it as a standard Windows form, but shouldn’t introduce any negative consequences.

This Show- function has two parameters of its own: FormOwner and KeepResults. Pass in a System.Windows.Forms.Form object to FormOwner and this dialog will become a child of that form. If you pass $true to KeepResults, the DialogResult code is placed in the pipeline when this form exits.

New in 1.05 is the proper handling of Tree View controls. The nodes themselves are a special case when compared to other controls. Variables ARE created to hold them, but they are auto-generated by VB as just TreeNode1, TreeNode2, etc. Since that’s kind of confusing and would have been difficult to handle under any circumstances, I chose not to attach them to the form like I do with other controls. However, VB, and this script, both assign the custom names that you specify. The node is accessible through the Tree View’s “Nodes” property by that custom name. So, if you name a node “NodeBeta” and it is attached to a Tree View named “tvBigTree” which is part of form “frmMain”, you can access it through $frmMain.tvBigTree.Nodes[‘NodeBeta’].

What the Script Doesn’t Do

The script only operates on the designer file, so it is oblivious to any event handlers.

The script is only aware of the System.Windows.Forms.Forms and System.Drawing namespaces. This means that it will be baffled by custom controls.

I have done my best to capture all possible settings for the forms and controls, with the exception of custom colors. I know those don’t work, and I didn’t consider it important enough to devote the necessary time to make them work. Even with all the effort I put into this, there is still a chance you’ll have to do some hand-tuning. The goal was to make a considerable reduction in the amount of time needed to make a decent form in PowerShell, not completely handle all possible scenarios. Your mileage may vary. The good news is that I’ve gotten it to successfully deal with some pretty complicated windows, so your need to do a lot of manual work should be minimal.

Updates

1.05

  • -KeepResults (a parameter of the emitted script) is now a Switch instead of a Boolean
  • Controls are not added to container controls until all controls are defined; this corrects issues such as text boxes inside group boxes being placed incorrectly
  • Multiline strings convert correctly
  • Detection of System.Windows.Forms.x and System.Drawing.x enumerators drastically improved
  • Processing of System.Drawing.Font declarations improved
  • Processing of cross-control references improved (such as AcceptButton and CancelButton)
  • Tree View controls and nodes are fully supported
  • Lines containing an apostrophe are not automatically considered a comment
  • Improved handling of parameters; positional parameters work as expected
  • Visual styles are enabled by default
  • Custom colors are properly translated

1.04

The biggest change in this version is that controls are now added as properties of the form. The problem was that only the form itself was added into the script variables. After the creation script exited, the controls themselves were only accessible through the form’s Controls property, which became especially onerous when working with controls inside containers on the form. Now, if you have a form named BigForm and a checkbox named ImportantCheckbox, that checkbox can now be manipulated from anywhere else in your script just by talking to $BigForm.ImportantCheckbox. Do remember to place any event handlers that reference this new property after it has been added.

The other thing is that I’ve cleaned up some of the formatting of the outputted script. Unfortunately, I can only go so far as the PowerShell implanted on this web page by WordPress isn’t perfect. It does help if you run this script through a tool that can remove trailing spaces. Notepad++ has this option; I haven’t yet found any PowerShell IDE that does.

The Script

The generating script is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. The emitted script is all yours. It has only been tested with VB Express 2013 and PowerShell 4.0; other environments may produce different results.

Without further ado, here it is:

<#
.SYNOPSIS
    Converts a .designer.vb file to a PS1 file.

.DESCRIPTION
    Parses a Visual Basic file that creates a Windows Form and generates a roughly equivalent PowerShell script.

.PARAMETER SourceFile
    Path to the .vb.designer file to be converted.

.PARAMETER DestinationScript
    Path to the output .ps1 file. The current directory is assumed if not specified and .ps1 is appended if not present.
    Mutually exclusive with ToPipeline parameter.

.PARAMETER ToPipeline
    Outputs the text to the pipeline. If there is nothing else in the pipeline, the script will appear on screen.
    Mutually exclusive with DestinationScript parameter.

.PARAMETER ScriptType
    StandAlone = A stand-alone script. When executed, this script will display the form. When the form closes, the script ends.
    DotSourced = A script that will expose the form and its Show-FormName function to the calling scope.
    Inline = A script chunk that resembles the output from DotSourced, but contains no help text or Parameter declarations

.PARAMETER ExcludeAssemblies
    Excludes the "Add-Type" lines for the .Net assemblies necessary to display Windows forms (System.Windows.Forms and System.Drawing).
    If you specify this parameter, your script must include these lines or the emitted script will be non-functional.

.PARAMETER DoNotEnableVisualStyles
	By default, a directive will be included to enable visual styles. This provides a more consistent experience between what you design
	in Visual Basic and what PowerShell displays. Use this parameter to leave visual styles at their default/current setting.

.LINK

https://etechgoodness.wordpress.com/2014/05/02/convert-visual-basic-form-to-powershell/

http://wp.me/p1pPNH-9r

.NOTES
	Updates in 1.05 (May 22, 2015)
	---------------
	-KeepResults (a parameter of the emitted script) is now a Switch instead of a Boolean
	Controls are not added to container controls until all controls are defined; this corrects issues such as text boxes inside group boxes being placed incorrectly
	Multiline strings convert correctly
	Detection of System.Windows.Forms.x and System.Drawing.x enumerators drastically improved
	Processing of System.Drawing.Font declarations improved
	Processing of cross-control references improved (such as AcceptButton and CancelButton)
	Tree View controls and nodes are fully supported
	Lines containing an apostrophe are not automatically considered a comment
	Improved handling of parameters; positional parameters work as expected
	Visual styles are enabled by default
	Custom colors are properly translated

	Updates in 1.04
	---------------
	Some clean-up of output format
	Controls are added as properties to the form so that they can be manipulated without indexing into $Form1.Controls[]

	Script by Eric Siron
	Licensed under a Creative Commons Attribution-ShareAlike 4.0 International License
#>
function ConvertTo-PowerShellForm
{
	[CmdletBinding(DefaultParameterSetName="ToPipeline")]
	param(
		[Parameter(HelpMessage="Enter the .designer.vb file to parse", Mandatory=$true, ValueFromPipeline=$true, Position=1)]
		[String]$SourceFile,

		[Parameter(Position=2, ParameterSetName="ToFile")]
		[String]$DestinationScript,

		[Parameter(ParameterSetName="ToPipeline")]
		[Switch]$ToPipeline = $false,

		[Parameter()]
		[ValidateSet("StandAlone", "DotSourced", "Inline")]
		[String]$ScriptType = "StandAlone",

		[Parameter()]
		[Switch]$ExcludeAssemblies = $false,

		[Parameter()]
		[Switch]$DoNotEnableVisualStyles = $false
	)

	BEGIN {
		$DotSourcedHeaderText = @'
<#
	Call Show-{0} to display {0} as a dialog.
	Use parameter FormOwner to specify another form as the owner of {0}.
	Use parameter KeepResults to return the DialogResult to the calling script.
#>

'@

		$StandAloneHeaderText = @'
<#
.SYNOPSIS
	Definition script for window {0}.

.DESCRIPTION
	Shows dialog box {0}

.PARAMETER FormOwner
	The window that owns {0}.

.PARAMETER KeepResults
	Places the dialog response code in the pipeline.

.OUTPUTS
	None by default

	System.Windows.Forms.DialogResult if -KeepResults is used
#>
[CmdletBinding()]
param(
	[PSObject]$FormOwner, [Switch]$KeepResults=$false
)

'@

	$AssemblyDeclarationsText = @'

## Add WinForm and Drawing assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

'@

	$VisualStylesText = @'
## Enable visual styles
[System.Windows.Forms.Application]::EnableVisualStyles()

'@

	$BuildFunctionLeadIn = @'

function Build-{0}
{{

'@

	$BuildFunctionLeadOut = @'
}} # Build-{0}

Build-{0}

'@

	$ShowFunction = @'

function Show-{0}
{{
	param($FormOwner = $null, [Switch]$KeepResults=$false)

	$ReturnCode = {1}.ShowDialog($null)
	if($KeepResults)
	{{
		$ReturnCode
	}}
}} # Show-{0}

'@
	}

	PROCESS
	{
		filter CommonConversions
		{
			param([String]$Line)
			$Line = $Line -replace '(?<=( = |\(|, ))New ([A-Za-z0-9\.]*)([\(][\)](?!={)){0,}', 'New-Object $2' # convert "New" to "New-Object", drop any empty parens at the end of the line, leave non-empty parens
			$Line = $Line -replace '(, New-Object)(.*?)(})', ', (New-Object$2})'
			$Line = $Line -replace 'CType\((\d+), Byte\)', '$1'	# byte conversions are not necessary
			$Line = $Line -replace '(True|False)$', '$$$0' # " = True" or " = False" ending a line converted to " = $True" or " = "$False"
			$Line = $Line -replace '(System\.)(Windows\.Forms|Drawing)(\.)(?!\S*\()(\S*)(\.)(\S*)', '[$1$2$3$4]::$6'	# changes enumerators. ex: System.Drawing.FontStyle.Bold to [System.Drawing.FontStyle]::Bold. -- (?!\S*\() negative lookahead to find parens to throw out items like System.Drawing.Point(1,2)
			$Line = $Line -replace "\(Me\.", '($$' # drop the $FormName. and leave control variable
			$Line
		}

		filter FormConversions
		{
			param([String]$Line)

			$Line = $Line -replace "(^\s*?|(?<= = ))Me\.", "$FormVar." # lines that start with Me. replaced with $FormName.; any starting whitespace removed
			$Line
		}

		filter ControlConversions
		{
			param([String]$Line)
			$Line = $Line -replace '^\s*?Me\.', '$$' # lines that start with "Me." shortened to the control's variable name; any starting whitespace removed
			if($Line -match '(\.AddRange\(New-Object \S*?\ ){(.*)}')# searching for AddRange
			{
				$Line = $Line -replace "(\.AddRange\(New-Object \S*?\ ){(.*)}", '.AddRange(@($2)'	# VB's AddRange to PowerShell's AddRange
				## AddRange in this context usually only adds text items or controls; text items should be ignored, but control items need to have a dollar-sign prepended
				$RangeItemsIn = $Matches[2].Split(',')
				$RangeItemsOut = @()
				foreach($RangeItem in $RangeItemsIn)
				{
					$RangeItem = $RangeItem.Trim()
					if($RangeItem[0] -ne '"') { $RangeItem = '$' + $RangeItem }
					$RangeItemsOut += ,($RangeItem)
				}
				$Line = $Line -replace $Matches[2], [String]::Join(', ', $RangeItemsOut)
			}
			$Line = $Line -replace '& _$', '+'	# convert strings broken across multiple code lines
			$Line = $Line -replace '(System.Drawing.Font\(.*)(!)', '$1'	# remove exclamation marks from font definitions
			$Line = $Line -replace 'System\.Drawing\.Color\.FromArgb[^\d]*(\d+)[^\d]*(\d+)[^\d]*(\d+)[^\d]*', '[System.Drawing.Color]::FromArgb($1, $2, $3)'	# Custom colors
			if($Line.Contains('[System.Windows.Forms.AnchorStyles]::'))
			{
				$AnchorPoints = @()
				if($Line.Contains('Top')) { $AnchorPoints += '[System.Windows.Forms.AnchorStyles]::Top' }
				if($Line.Contains('Bottom')) { $AnchorPoints += '[System.Windows.Forms.AnchorStyles]::Bottom' }
				if($Line.Contains('Left')) { $AnchorPoints += '[System.Windows.Forms.AnchorStyles]::Left' }
				if($Line.Contains('Right')) { $AnchorPoints += '[System.Windows.Forms.AnchorStyles]::Right' }
				$AnchorSettings = [String]::Join(' -bor ', $AnchorPoints)
				if($Line -match '^\s*\$.*\.Anchor = ')
				{
					$Line = $Matches[0] + $AnchorSettings
				}
				else
				{
					$Line = "`t`t -bor " + $AnchorSettings
				}
			}
			if($Line -match '(\S*) As System.Windows.Forms.TreeNode')
			{
				$Script:TreeNodeVars += $Matches[1]
				$Line = $Line -replace '^\s*Dim (\S*) As System.Windows.Forms.TreeNode', '$$$1'
				if($Line -match '\(New-Object System.Windows.Forms.TreeNode {([^}]*)}\)')
				{
					$SubNodesIn = $Matches[1].Split(',')
					$SubNodesOut = @()
					foreach($SubNode in $SubNodesIn)
					{
						$SubNode = $SubNode.Trim()
						if($SubNode[0] -ne '"') { $SubNode = '$' + $SubNode }
						$SubNodesOut += ,($SubNode)
					}
					$SubNodesOutLine = [String]::Join(', ', $SubNodesOut)
					$Line = $Line -replace '\(New-Object System.Windows.Forms.TreeNode {([^}]*)}\)', "@($SubNodesOutLine)"
				}
			}
			$Line
		}

		function ConvertTo-PowerShellForm
		{
			if(-not(Test-Path -Path $SourceFile))
			{
				throw "$SourceFile not found"
			}
			$RawFileData = Get-Content $SourceFile

			if($RawFileData[0] -ne "<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _")
			{
				throw "$SourceFile does not appear to be a valid VB Designer file"
			}

			$FormShortName = $RawFileData[1] -replace "Partial Class "
			New-Variable -Name FormVar -Value "`$$FormShortName"

			$OutputFormDefinition = @("`t## $FormShortName Form ##", "`t`$Script:$FormShortName = New-Object System.Windows.Forms.Form")
			$OutputControlDeclarations = @("", "`t## $FormShortName Controls ##")
			$OutputControlDefinitions = @("", "`t## $FormShortName Control Constructions ##")
			$OutputControlAddToForm = @("", "`t## Adding controls to Form $FormShortName")
			$OutputControlAddToContainer = @("", "`t## Adding controls to container controls")
			$ControlVars = @("", "`t## Adding controls as properties to Form $FormShortName")
			$Script:TreeNodeVars = @()
			$TreeNodeSettings = @("", "`t## Configuring tree nodes")
			$TextToWatchForNext = "Private Sub InitializeComponent()"
			$InInitComponent = $false
			$InControlDeclarations = $false
			$InControlDefinitions = $false
			$InFormDefinition = $false
			$CurrentControl = $null

			foreach($CodeLine in $RawFileData)
			{
				if($CodeLine -notmatch $TextToWatchForNext)
				{
					if($InInitComponent -and $InControlDeclarations)
					{
						if($CodeLine -match "New System.Windows.Forms")
						{
							$ControlDeclaration = CommonConversions -Line $CodeLine
							$ControlDeclaration = ControlConversions -Line $ControlDeclaration
							$OutputControlDeclarations += ("`t" + $ControlDeclaration)
						}
					}
					elseif($InControlDefinitions)
					{
						if($CodeLine -match "'$FormShortName") #vb sets up the form after all the controls, and prepends it with some comments, one of which is in the format 'FormName
						{
							$InControlDeclarations = $false
							$InControlDefinitions = $false
							$InFormDefinition = $true
						}
						elseif($CodeLine -match "^\s*'.*$")
						{
							# this line is commented out (but isn't the form's name, that was caught in a previous check), so just eat it
						}
						else
						{
							if($CurrentControl -eq $null -and $CodeLine -match "(?<=\.)(.*?)(?=\.)")
							{
								$CurrentControl = $Matches[1]
								$ControlVars += "`t`$$FormShortName | Add-Member -MemberType NoteProperty -Name $CurrentControl -Value `$$CurrentControl"
								$OutputControlDefinitions += @("", "`t# Control: $CurrentControl")
							}
							$ControlDefinition = CommonConversions -Line $CodeLine
							$ControlDefinition = ControlConversions -Line $ControlDefinition
							if($ControlDefinition.Contains("$CurrentControl.Controls.Add("))
							{
								$OutputControlAddToContainer += ("`t" + $ControlDefinition)
							}
							else
							{
								if($ControlDefinition -match '^\s*-bor')
								{	# if a line starts with -bor, it is a continuation of the previous line. PS can't parse the break unless the -bor finishes the line. The easiest way to handle this is to just make it one big line.
									$OutputControlDefinitions[($OutputControlDefinitions.Length - 1)] += ($ControlDefinition -replace '\t+?', '')
								}
								else
								{
									foreach($TreeNode in $TreeNodeVars)
									{
										if($ControlDefinition -match "^\s*?($TreeNode)")
										{
											$ControlDefinition = $ControlDefinition -replace "^\s*?($TreeNode)", "`$$TreeNode"
										}
									}
									$OutputControlDefinitions += ("`t" + $ControlDefinition)
								}
							}
						}
					}
					elseif($InFormDefinition)
					{
						if(($CodeLine -notmatch "=") -and $CodeLine -match "\.Add\(")
						{
							$ControlAddition = CommonConversions -Line $CodeLine
							$ControlAddition = FormConversions -Line $ControlAddition
							$OutputControlAddToForm += ("`t" + $ControlAddition)
						}
						elseif($CodeLine -match "=")
						{
							$FormDefinition = CommonConversions -Line $CodeLine
							$FormDefinition = FormConversions -Line $FormDefinition
							if($FormDefinition -match "\.SizeF\(")
							{
								$FormDefinition = $FormDefinition -replace "!"
							}
							$OutputFormDefinition += ("`t" + $FormDefinition)
						}
					}
				}
				else
				{
					if($TextToWatchForNext -eq "Private Sub InitializeComponent()")
					{
						$InInitComponent = $true
						$InControlDeclarations = $true
						$TextToWatchForNext = "'$"
					}
					elseif($TextToWatchForNext -eq "'$")
					{
						if($InControlDeclarations)
						{
							$InControlDeclarations = $false
							$InControlDefinitions = $true
						}
						elseif($InControlDefinitions)
						{
							$CurrentControl = $null
						}
					}
				}
			}

			$OutputText = New-Object System.Text.StringBuilder("")
			switch($ScriptType)
			{
				"StandAlone" {
					$OutputText.AppendFormat($StandAloneHeaderText, $FormShortName) | Out-Null
				}
				"DotSourced" {
					$OutputText.AppendFormat($DotSourcedHeaderText, $FormShortName) | Out-Null
				}
				default {
				}
			}

			if(-not($ExcludeAssemblies))
			{
				$OutputText.Append($AssemblyDeclarationsText) | Out-Null
			}
			if(-not($DoNotEnableVisualStyles))
			{
				$OutputText.Append($VisualStylesText) | Out-Null
			}

			$OutputText.AppendFormat($ShowFunction, $FormShortName, $FormVar) | Out-Null
			$OutputText.Append(($BuildFunctionLeadIn -f $FormShortName, "")) | Out-Null

			$OutputFormDefinition | ForEach-Object { $OutputText.AppendLine($_) | Out-Null }
			$OutputControlDeclarations | ForEach-Object { $OutputText.AppendLine($_) | Out-Null }
			$OutputControlDefinitions | ForEach-Object { $OutputText.AppendLine($_) | Out-Null }
			$OutputControlAddToForm | ForEach-Object { $OutputText.AppendLine($_) | Out-Null }
			$OutputControlAddToContainer | ForEach-Object { $OutputText.AppendLine($_) | Out-Null }
			$ControlVars | ForEach-Object { $OutputText.AppendLine($_) | Out-Null }
			Write-Host $ControlList

			$OutputText.AppendFormat($BuildFunctionLeadOut, $FormShortName) | Out-Null

			if($ScriptType -eq "StandAlone")
			{
				$OutputText.AppendLine("Show-$FormShortName") | Out-Null
			}

			if(-not([String]::IsNullOrEmpty($DestinationScript)))
			{
				if([String]::IsNullOrEmpty((Split-Path -Path $DestinationScript)))
				{
					$DestinationScript = ".\" + $DestinationScript
				}
				if($DestinationScript -notmatch "\.ps1$")
				{
					$DestinationScript += ".ps1"
				}
				Set-Content -Path $DestinationScript -Value $OutputText.ToString() # We did enough checking, let PS handle any invalid path problems from here
			}
			else
			{
				$OutputText.ToString()
			}
		}

		ConvertTo-PowerShellForm
	}

	END {}
}

Sample

Running the following file through, using defaults:

<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class TestForm
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()> _
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> _
    Private Sub InitializeComponent()
		Dim TreeNode1 As System.Windows.Forms.TreeNode = New System.Windows.Forms.TreeNode("Child Item 1")
		Dim TreeNode2 As System.Windows.Forms.TreeNode = New System.Windows.Forms.TreeNode("Root 1", New System.Windows.Forms.TreeNode() {TreeNode1})
		Dim TreeNode3 As System.Windows.Forms.TreeNode = New System.Windows.Forms.TreeNode("Way Out There")
		Dim TreeNode4 As System.Windows.Forms.TreeNode = New System.Windows.Forms.TreeNode("Down to There")
		Dim TreeNode5 As System.Windows.Forms.TreeNode = New System.Windows.Forms.TreeNode("The Other Child Item 1", New System.Windows.Forms.TreeNode() {TreeNode3, TreeNode4})
		Dim TreeNode6 As System.Windows.Forms.TreeNode = New System.Windows.Forms.TreeNode("Root 2", New System.Windows.Forms.TreeNode() {TreeNode5})
		Me.tvMenu = New System.Windows.Forms.TreeView()
		Me.tcMaster = New System.Windows.Forms.TabControl()
		Me.tabOne = New System.Windows.Forms.TabPage()
		Me.tabTwo = New System.Windows.Forms.TabPage()
		Me.lblNoOneLikesMe = New System.Windows.Forms.Label()
		Me.gbContainer = New System.Windows.Forms.GroupBox()
		Me.tbDisplay = New System.Windows.Forms.TextBox()
		Me.rbOption1 = New System.Windows.Forms.RadioButton()
		Me.rbOption2 = New System.Windows.Forms.RadioButton()
		Me.btnBig = New System.Windows.Forms.Button()
		Me.btnOK = New System.Windows.Forms.Button()
		Me.btnCancel = New System.Windows.Forms.Button()
		Me.lbThings = New System.Windows.Forms.ListBox()
		Me.cbColor = New System.Windows.Forms.CheckBox()
		Me.tcMaster.SuspendLayout()
		Me.tabOne.SuspendLayout()
		Me.tabTwo.SuspendLayout()
		Me.gbContainer.SuspendLayout()
		Me.SuspendLayout()
		'
		'tvMenu
		'
		Me.tvMenu.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
				Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
		Me.tvMenu.Location = New System.Drawing.Point(12, 12)
		Me.tvMenu.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tvMenu.Name = "tvMenu"
		TreeNode1.Name = "RootNode1ChildNode1"
		TreeNode1.Text = "Child Item 1"
		TreeNode2.Name = "RootNode1"
		TreeNode2.Text = "Root 1"
		TreeNode3.Name = "RootNode2ChildNode1ThirdLevel1"
		TreeNode3.Text = "Way Out There"
		TreeNode4.Name = "RootNode2ChildNode1ThirdLevel2"
		TreeNode4.Text = "Down to There"
		TreeNode5.Name = "RootNode1ChildNode1"
		TreeNode5.Text = "The Other Child Item 1"
		TreeNode6.Name = "Root2"
		TreeNode6.Text = "Root 2"
		Me.tvMenu.Nodes.AddRange(New System.Windows.Forms.TreeNode() {TreeNode2, TreeNode6})
		Me.tvMenu.Size = New System.Drawing.Size(161, 428)
		Me.tvMenu.TabIndex = 0
		'
		'tcMaster
		'
		Me.tcMaster.Controls.Add(Me.tabOne)
		Me.tcMaster.Controls.Add(Me.tabTwo)
		Me.tcMaster.Location = New System.Drawing.Point(180, 13)
		Me.tcMaster.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tcMaster.Name = "tcMaster"
		Me.tcMaster.SelectedIndex = 0
		Me.tcMaster.Size = New System.Drawing.Size(516, 378)
		Me.tcMaster.TabIndex = 1
		'
		'tabOne
		'
		Me.tabOne.Controls.Add(Me.gbContainer)
		Me.tabOne.Location = New System.Drawing.Point(4, 22)
		Me.tabOne.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tabOne.Name = "tabOne"
		Me.tabOne.Padding = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tabOne.Size = New System.Drawing.Size(508, 352)
		Me.tabOne.TabIndex = 0
		Me.tabOne.Text = "First Tab"
		Me.tabOne.UseVisualStyleBackColor = True
		'
		'tabTwo
		'
		Me.tabTwo.Controls.Add(Me.lblNoOneLikesMe)
		Me.tabTwo.Location = New System.Drawing.Point(4, 22)
		Me.tabTwo.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tabTwo.Name = "tabTwo"
		Me.tabTwo.Padding = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tabTwo.Size = New System.Drawing.Size(508, 352)
		Me.tabTwo.TabIndex = 1
		Me.tabTwo.Text = "Second Tab"
		Me.tabTwo.UseVisualStyleBackColor = True
		'
		'lblNoOneLikesMe
		'
		Me.lblNoOneLikesMe.AutoSize = True
		Me.lblNoOneLikesMe.Location = New System.Drawing.Point(6, 4)
		Me.lblNoOneLikesMe.Name = "lblNoOneLikesMe"
		Me.lblNoOneLikesMe.Size = New System.Drawing.Size(441, 13)
		Me.lblNoOneLikesMe.TabIndex = 0
		Me.lblNoOneLikesMe.Text = "Help! I'm stuck on the second tab of a demo box where no one will ever hear from " & _
	 "me again."
		'
		'gbContainer
		'
		Me.gbContainer.Controls.Add(Me.cbColor)
		Me.gbContainer.Controls.Add(Me.lbThings)
		Me.gbContainer.Controls.Add(Me.btnBig)
		Me.gbContainer.Controls.Add(Me.rbOption2)
		Me.gbContainer.Controls.Add(Me.rbOption1)
		Me.gbContainer.Controls.Add(Me.tbDisplay)
		Me.gbContainer.Location = New System.Drawing.Point(6, 6)
		Me.gbContainer.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.gbContainer.Name = "gbContainer"
		Me.gbContainer.Padding = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.gbContainer.Size = New System.Drawing.Size(496, 340)
		Me.gbContainer.TabIndex = 0
		Me.gbContainer.TabStop = False
		Me.gbContainer.Text = "I'm in a Tab"
		'
		'tbDisplay
		'
		Me.tbDisplay.Location = New System.Drawing.Point(6, 19)
		Me.tbDisplay.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.tbDisplay.Name = "tbDisplay"
		Me.tbDisplay.ReadOnly = True
		Me.tbDisplay.Size = New System.Drawing.Size(251, 20)
		Me.tbDisplay.TabIndex = 0
		Me.tbDisplay.Text = "I'm in a box"
		'
		'rbOption1
		'
		Me.rbOption1.AutoSize = True
		Me.rbOption1.Location = New System.Drawing.Point(6, 45)
		Me.rbOption1.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.rbOption1.Name = "rbOption1"
		Me.rbOption1.Size = New System.Drawing.Size(79, 17)
		Me.rbOption1.TabIndex = 1
		Me.rbOption1.TabStop = True
		Me.rbOption1.Text = "One Option"
		Me.rbOption1.UseVisualStyleBackColor = True
		'
		'rbOption2
		'
		Me.rbOption2.AutoSize = True
		Me.rbOption2.Location = New System.Drawing.Point(6, 69)
		Me.rbOption2.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.rbOption2.Name = "rbOption2"
		Me.rbOption2.Size = New System.Drawing.Size(97, 17)
		Me.rbOption2.TabIndex = 2
		Me.rbOption2.TabStop = True
		Me.rbOption2.Text = "A Better Option"
		Me.rbOption2.UseVisualStyleBackColor = True
		'
		'btnBig
		'
		Me.btnBig.BackColor = System.Drawing.Color.Maroon
		Me.btnBig.Font = New System.Drawing.Font("Microsoft Sans Serif", 14.0!, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
		Me.btnBig.ForeColor = System.Drawing.SystemColors.ControlLightLight
		Me.btnBig.Location = New System.Drawing.Point(75, 250)
		Me.btnBig.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.btnBig.Name = "btnBig"
		Me.btnBig.Size = New System.Drawing.Size(346, 82)
		Me.btnBig.TabIndex = 3
		Me.btnBig.Text = "A Big Colorful Button"
		Me.btnBig.UseVisualStyleBackColor = False
		'
		'btnOK
		'
		Me.btnOK.Location = New System.Drawing.Point(575, 411)
		Me.btnOK.Name = "btnOK"
		Me.btnOK.Size = New System.Drawing.Size(116, 28)
		Me.btnOK.TabIndex = 2
		Me.btnOK.Text = "&OK"
		Me.btnOK.UseVisualStyleBackColor = True
		'
		'btnCancel
		'
		Me.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel
		Me.btnCancel.Location = New System.Drawing.Point(453, 411)
		Me.btnCancel.Name = "btnCancel"
		Me.btnCancel.Size = New System.Drawing.Size(116, 28)
		Me.btnCancel.TabIndex = 3
		Me.btnCancel.Text = "&Cancel"
		Me.btnCancel.UseVisualStyleBackColor = True
		'
		'lbThings
		'
		Me.lbThings.FormattingEnabled = True
		Me.lbThings.Items.AddRange(New Object() {"That Thing", "That Other Thing", "One More Thing", "No Thing"})
		Me.lbThings.Location = New System.Drawing.Point(6, 93)
		Me.lbThings.Name = "lbThings"
		Me.lbThings.Size = New System.Drawing.Size(484, 147)
		Me.lbThings.TabIndex = 4
		'
		'cbColor
		'
		Me.cbColor.AutoSize = True
		Me.cbColor.BackColor = System.Drawing.Color.FromArgb(CType(CType(192, Byte), Integer), CType(CType(255, Byte), Integer), CType(CType(255, Byte), Integer))
		Me.cbColor.Checked = True
		Me.cbColor.CheckState = System.Windows.Forms.CheckState.Checked
		Me.cbColor.Location = New System.Drawing.Point(263, 69)
		Me.cbColor.Name = "cbColor"
		Me.cbColor.Size = New System.Drawing.Size(128, 17)
		Me.cbColor.TabIndex = 5
		Me.cbColor.Text = "Isn't this a nice color?"
		Me.cbColor.UseVisualStyleBackColor = False
		'
		'TestForm
		'
		Me.AcceptButton = Me.btnOK
		Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
		Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
		Me.CancelButton = Me.btnCancel
		Me.ClientSize = New System.Drawing.Size(708, 451)
		Me.Controls.Add(Me.btnCancel)
		Me.Controls.Add(Me.btnOK)
		Me.Controls.Add(Me.tcMaster)
		Me.Controls.Add(Me.tvMenu)
		Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
		Me.Margin = New System.Windows.Forms.Padding(3, 4, 3, 4)
		Me.MaximizeBox = False
		Me.Name = "TestForm"
		Me.Text = "TestForm"
		Me.tcMaster.ResumeLayout(False)
		Me.tabOne.ResumeLayout(False)
		Me.tabTwo.ResumeLayout(False)
		Me.tabTwo.PerformLayout()
		Me.gbContainer.ResumeLayout(False)
		Me.gbContainer.PerformLayout()
		Me.ResumeLayout(False)

	End Sub
	Friend WithEvents tvMenu As System.Windows.Forms.TreeView
	Friend WithEvents tcMaster As System.Windows.Forms.TabControl
	Friend WithEvents tabOne As System.Windows.Forms.TabPage
	Friend WithEvents gbContainer As System.Windows.Forms.GroupBox
	Friend WithEvents btnBig As System.Windows.Forms.Button
	Friend WithEvents rbOption2 As System.Windows.Forms.RadioButton
	Friend WithEvents rbOption1 As System.Windows.Forms.RadioButton
	Friend WithEvents tbDisplay As System.Windows.Forms.TextBox
	Friend WithEvents tabTwo As System.Windows.Forms.TabPage
	Friend WithEvents lblNoOneLikesMe As System.Windows.Forms.Label
	Friend WithEvents btnOK As System.Windows.Forms.Button
	Friend WithEvents btnCancel As System.Windows.Forms.Button
	Friend WithEvents lbThings As System.Windows.Forms.ListBox
	Friend WithEvents cbColor As System.Windows.Forms.CheckBox
End Class

Produces:

<#
.SYNOPSIS
	Definition script for window TestForm.
 
.DESCRIPTION
	Shows dialog box TestForm
 
.PARAMETER FormOwner
	The window that owns TestForm.
 
.PARAMETER KeepResults
	Places the dialog response code in the pipeline.
 
.OUTPUTS
	None by default
 
	System.Windows.Forms.DialogResult if -KeepResults is used
#>
[CmdletBinding()]
param(
	[PSObject]$FormOwner, [Switch]$KeepResults=$false
)
  
## Add WinForm and Drawing assemblies
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
## Enable visual styles
[System.Windows.Forms.Application]::EnableVisualStyles()
 
function Show-TestForm
{
	param($FormOwner = $null, [Switch]$KeepResults=$false)
 
	$ReturnCode = $TestForm.ShowDialog($null)
	if($KeepResults)
	{
		$ReturnCode
	}
} # Show-TestForm
  
function Build-TestForm
{
 	## TestForm Form ##
	$Script:TestForm = New-Object System.Windows.Forms.Form
	$TestForm.AcceptButton = $TestForm.btnOK
	$TestForm.AutoScaleDimensions = New-Object System.Drawing.SizeF(6.0, 13.0)
	$TestForm.AutoScaleMode = [System.Windows.Forms.AutoScaleMode]::Font
	$TestForm.CancelButton = $TestForm.btnCancel
	$TestForm.ClientSize = New-Object System.Drawing.Size(708, 451)
	$TestForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
	$TestForm.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$TestForm.MaximizeBox = $False
	$TestForm.Name = "TestForm"
	$TestForm.Text = "TestForm"

	## TestForm Controls ##
	$TreeNode1 = New-Object System.Windows.Forms.TreeNode("Child Item 1")
	$TreeNode2 = New-Object System.Windows.Forms.TreeNode("Root 1", @($TreeNode1))
	$TreeNode3 = New-Object System.Windows.Forms.TreeNode("Way Out There")
	$TreeNode4 = New-Object System.Windows.Forms.TreeNode("Down to There")
	$TreeNode5 = New-Object System.Windows.Forms.TreeNode("The Other Child Item 1", @($TreeNode3, $TreeNode4))
	$TreeNode6 = New-Object System.Windows.Forms.TreeNode("Root 2", @($TreeNode5))
	$tvMenu = New-Object System.Windows.Forms.TreeView
	$tcMaster = New-Object System.Windows.Forms.TabControl
	$tabOne = New-Object System.Windows.Forms.TabPage
	$tabTwo = New-Object System.Windows.Forms.TabPage
	$lblNoOneLikesMe = New-Object System.Windows.Forms.Label
	$gbContainer = New-Object System.Windows.Forms.GroupBox
	$tbDisplay = New-Object System.Windows.Forms.TextBox
	$rbOption1 = New-Object System.Windows.Forms.RadioButton
	$rbOption2 = New-Object System.Windows.Forms.RadioButton
	$btnBig = New-Object System.Windows.Forms.Button
	$btnOK = New-Object System.Windows.Forms.Button
	$btnCancel = New-Object System.Windows.Forms.Button
	$lbThings = New-Object System.Windows.Forms.ListBox
	$cbColor = New-Object System.Windows.Forms.CheckBox

	## TestForm Control Constructions ##

	# Control: tvMenu
	$tvMenu.Anchor = [System.Windows.Forms.AnchorStyles]::Top -bor [System.Windows.Forms.AnchorStyles]::Bottom -bor [System.Windows.Forms.AnchorStyles]::Left
	$tvMenu.Location = New-Object System.Drawing.Point(12, 12)
	$tvMenu.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tvMenu.Name = "tvMenu"
	$TreeNode1.Name = "RootNode1ChildNode1"
	$TreeNode1.Text = "Child Item 1"
	$TreeNode2.Name = "RootNode1"
	$TreeNode2.Text = "Root 1"
	$TreeNode3.Name = "RootNode2ChildNode1ThirdLevel1"
	$TreeNode3.Text = "Way Out There"
	$TreeNode4.Name = "RootNode2ChildNode1ThirdLevel2"
	$TreeNode4.Text = "Down to There"
	$TreeNode5.Name = "RootNode1ChildNode1"
	$TreeNode5.Text = "The Other Child Item 1"
	$TreeNode6.Name = "Root2"
	$TreeNode6.Text = "Root 2"
	$tvMenu.Nodes.AddRange(@($TreeNode2, $TreeNode6))
	$tvMenu.Size = New-Object System.Drawing.Size(161, 428)
	$tvMenu.TabIndex = 0

	# Control: tcMaster
	$tcMaster.Location = New-Object System.Drawing.Point(180, 13)
	$tcMaster.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tcMaster.Name = "tcMaster"
	$tcMaster.SelectedIndex = 0
	$tcMaster.Size = New-Object System.Drawing.Size(516, 378)
	$tcMaster.TabIndex = 1

	# Control: tabOne
	$tabOne.Location = New-Object System.Drawing.Point(4, 22)
	$tabOne.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tabOne.Name = "tabOne"
	$tabOne.Padding = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tabOne.Size = New-Object System.Drawing.Size(508, 352)
	$tabOne.TabIndex = 0
	$tabOne.Text = "First Tab"
	$tabOne.UseVisualStyleBackColor = $True

	# Control: tabTwo
	$tabTwo.Location = New-Object System.Drawing.Point(4, 22)
	$tabTwo.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tabTwo.Name = "tabTwo"
	$tabTwo.Padding = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tabTwo.Size = New-Object System.Drawing.Size(508, 352)
	$tabTwo.TabIndex = 1
	$tabTwo.Text = "Second Tab"
	$tabTwo.UseVisualStyleBackColor = $True

	# Control: lblNoOneLikesMe
	$lblNoOneLikesMe.AutoSize = $True
	$lblNoOneLikesMe.Location = New-Object System.Drawing.Point(6, 4)
	$lblNoOneLikesMe.Name = "lblNoOneLikesMe"
	$lblNoOneLikesMe.Size = New-Object System.Drawing.Size(441, 13)
	$lblNoOneLikesMe.TabIndex = 0
	$lblNoOneLikesMe.Text = "Help! I'm stuck on the second tab of a demo box where no one will ever hear from " +
		 "me again."

	# Control: gbContainer
	$gbContainer.Location = New-Object System.Drawing.Point(6, 6)
	$gbContainer.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$gbContainer.Name = "gbContainer"
	$gbContainer.Padding = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$gbContainer.Size = New-Object System.Drawing.Size(496, 340)
	$gbContainer.TabIndex = 0
	$gbContainer.TabStop = $False
	$gbContainer.Text = "I'm in a Tab"

	# Control: tbDisplay
	$tbDisplay.Location = New-Object System.Drawing.Point(6, 19)
	$tbDisplay.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$tbDisplay.Name = "tbDisplay"
	$tbDisplay.ReadOnly = $True
	$tbDisplay.Size = New-Object System.Drawing.Size(251, 20)
	$tbDisplay.TabIndex = 0
	$tbDisplay.Text = "I'm in a box"

	# Control: rbOption1
	$rbOption1.AutoSize = $True
	$rbOption1.Location = New-Object System.Drawing.Point(6, 45)
	$rbOption1.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$rbOption1.Name = "rbOption1"
	$rbOption1.Size = New-Object System.Drawing.Size(79, 17)
	$rbOption1.TabIndex = 1
	$rbOption1.TabStop = $True
	$rbOption1.Text = "One Option"
	$rbOption1.UseVisualStyleBackColor = $True

	# Control: rbOption2
	$rbOption2.AutoSize = $True
	$rbOption2.Location = New-Object System.Drawing.Point(6, 69)
	$rbOption2.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$rbOption2.Name = "rbOption2"
	$rbOption2.Size = New-Object System.Drawing.Size(97, 17)
	$rbOption2.TabIndex = 2
	$rbOption2.TabStop = $True
	$rbOption2.Text = "A Better Option"
	$rbOption2.UseVisualStyleBackColor = $True

	# Control: btnBig
	$btnBig.BackColor = [System.Drawing.Color]::Maroon
	$btnBig.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 14.0, [System.Drawing.FontStyle]::Bold, [System.Drawing.GraphicsUnit]::Point, 0)
	$btnBig.ForeColor = [System.Drawing.SystemColors]::ControlLightLight
	$btnBig.Location = New-Object System.Drawing.Point(75, 250)
	$btnBig.Margin = New-Object System.Windows.Forms.Padding(3, 4, 3, 4)
	$btnBig.Name = "btnBig"
	$btnBig.Size = New-Object System.Drawing.Size(346, 82)
	$btnBig.TabIndex = 3
	$btnBig.Text = "A Big Colorful Button"
	$btnBig.UseVisualStyleBackColor = $False

	# Control: btnOK
	$btnOK.Location = New-Object System.Drawing.Point(575, 411)
	$btnOK.Name = "btnOK"
	$btnOK.Size = New-Object System.Drawing.Size(116, 28)
	$btnOK.TabIndex = 2
	$btnOK.Text = "&OK"
	$btnOK.UseVisualStyleBackColor = $True

	# Control: btnCancel
	$btnCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
	$btnCancel.Location = New-Object System.Drawing.Point(453, 411)
	$btnCancel.Name = "btnCancel"
	$btnCancel.Size = New-Object System.Drawing.Size(116, 28)
	$btnCancel.TabIndex = 3
	$btnCancel.Text = "&Cancel"
	$btnCancel.UseVisualStyleBackColor = $True

	# Control: lbThings
	$lbThings.FormattingEnabled = $True
	$lbThings.Items.AddRange(@("That Thing", "That Other Thing", "One More Thing", "No Thing"))
	$lbThings.Location = New-Object System.Drawing.Point(6, 93)
	$lbThings.Name = "lbThings"
	$lbThings.Size = New-Object System.Drawing.Size(484, 147)
	$lbThings.TabIndex = 4

	# Control: cbColor
	$cbColor.AutoSize = $True
	$cbColor.BackColor = [System.Drawing.Color]::FromArgb(192, 255, 255)
	$cbColor.Checked = $True
	$cbColor.CheckState = [System.Windows.Forms.CheckState]::Checked
	$cbColor.Location = New-Object System.Drawing.Point(263, 69)
	$cbColor.Name = "cbColor"
	$cbColor.Size = New-Object System.Drawing.Size(128, 17)
	$cbColor.TabIndex = 5
	$cbColor.Text = "Isn't this a nice color?"
	$cbColor.UseVisualStyleBackColor = $False

	## Adding controls to Form TestForm
	$TestForm.Controls.Add($btnCancel)
	$TestForm.Controls.Add($btnOK)
	$TestForm.Controls.Add($tcMaster)
	$TestForm.Controls.Add($tvMenu)

	## Adding controls to container controls
	$tcMaster.Controls.Add($tabOne)
	$tcMaster.Controls.Add($tabTwo)
	$tabOne.Controls.Add($gbContainer)
	$tabTwo.Controls.Add($lblNoOneLikesMe)
	$gbContainer.Controls.Add($cbColor)
	$gbContainer.Controls.Add($lbThings)
	$gbContainer.Controls.Add($btnBig)
	$gbContainer.Controls.Add($rbOption2)
	$gbContainer.Controls.Add($rbOption1)
	$gbContainer.Controls.Add($tbDisplay)

	## Adding controls as properties to Form TestForm
	$TestForm | Add-Member -MemberType NoteProperty -Name tvMenu -Value $tvMenu
	$TestForm | Add-Member -MemberType NoteProperty -Name tcMaster -Value $tcMaster
	$TestForm | Add-Member -MemberType NoteProperty -Name tabOne -Value $tabOne
	$TestForm | Add-Member -MemberType NoteProperty -Name tabTwo -Value $tabTwo
	$TestForm | Add-Member -MemberType NoteProperty -Name lblNoOneLikesMe -Value $lblNoOneLikesMe
	$TestForm | Add-Member -MemberType NoteProperty -Name gbContainer -Value $gbContainer
	$TestForm | Add-Member -MemberType NoteProperty -Name tbDisplay -Value $tbDisplay
	$TestForm | Add-Member -MemberType NoteProperty -Name rbOption1 -Value $rbOption1
	$TestForm | Add-Member -MemberType NoteProperty -Name rbOption2 -Value $rbOption2
	$TestForm | Add-Member -MemberType NoteProperty -Name btnBig -Value $btnBig
	$TestForm | Add-Member -MemberType NoteProperty -Name btnOK -Value $btnOK
	$TestForm | Add-Member -MemberType NoteProperty -Name btnCancel -Value $btnCancel
	$TestForm | Add-Member -MemberType NoteProperty -Name lbThings -Value $lbThings
	$TestForm | Add-Member -MemberType NoteProperty -Name cbColor -Value $cbColor
} # Build-TestForm
 
Build-TestForm
 Show-TestForm

Which, when executed, displays:

VB to PowerShell Demo Form

VB to PowerShell Demo Form

Advertisements

Leave a Reply

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

%d bloggers like this: