1

I have a winform application which populate some data after I click on $button_UpdateTS, how do I add the data stored in a variable, that comes available after I click on that button ?

The data I want in my list view is stored in an array called $results

$button_UpdateTS = New-Object System.Windows.Forms.Button
$button_UpdateTS.Location = New-Object System.Drawing.Size(15, 954)
$button_UpdateTS.Size = New-Object System.Drawing.Size(320, 32)
$button_UpdateTS.TextAlign = "MiddleCenter"
$button_UpdateTS.Text = “Update Tasksequence”
$button_UpdateTS.Add_Click( { $Results = Set-DynamicVariables 
-Manufacturer "$($listview_Vendor.SelectedItems)" 
-TSPackageID "$($ListView_Tasksequences.SelectedItems.SubItems[1].Text)" -WhatIf })
    $Form.Controls.Add($button_UpdateTS)

Which gives me :

$Results = 
SKUNotExistsDriverName    : XPS Notebook 9560
SKUNotExistsDriverID      : PS10053F
SKUNotExistsDriverSKU     : 07BE
SKUNotExistsDriverVersion : A12
SKUNotExistsBIOSName      : XPS Notebook 9560
SKUNotExistsBIOSID        : PS10053E
SKUNotExistsBIOSSKU       : 07BE
SKUNotExistsBIOSVersion   : 1.15.0

This is the list I want it stored in :

$Global:listview_NotExists_SKU = New-Object System.Windows.Forms.ListView
$listview_NotExists_SKU.Location = New-Object System.Drawing.Size(515, 670)
$listview_NotExists_SKU.Size = New-Object System.Drawing.Size(486, 235)
$listview_NotExists_SKU.View = "Details"
$listview_NotExists_SKU.FullRowSelect = $true
$listview_NotExists_SKU.MultiSelect = $true
$listview_NotExists_SKU.Sorting = "None"
$listview_NotExists_SKU.AllowColumnReorder = $true
$listview_NotExists_SKU.GridLines = $true
$listview_NotExists_SKU.Add_ColumnClick( { SortListView $this $_.Column })
$Form.Controls.Add($listview_NotExists_SKU)

I tried with this function, but that does not work:

Function Get-Results {
        ForEach ($Result in $Results) {
            $listview_NotExists_SKU.Items.Add($Result) 
       }
}

$Form.Add_Shown( { $Form.Load; Get-results })
0

1 Answer 1

1

Because an event-handling script block added with e.g. .Add_Click() runs in in a child scope of the caller, assigning to variable $Results there ($Results = ...) creates a scope-local variable that neither the scope in which the event handler was set up nor subsequently invoked event handlers can see.

To create a variable in the script scope, which subsequently invoked event handlers can see as well[1], use the $script: scope specifier:

$button_UpdateTS.Add_Click( { $script:Results = ... } )

Note:

  • If the scope in which the event handlers are set up isn't the script scope (e.g., if the code is inside a function) and you want to more generically reference the parent scope from within an event handler, use Set-Variable -Scope 1 -Name Results -Value ....[1]

  • An alternative to setting a variable in the parent scope explicitly is to use a hashtable defined in the parent scope whose entries can be used in lieu of variables that the event-handler script blocks can modify too.[2] See this answer for an example.


[1] For more information about scopes in PowerShell, see the bottom section of this answer.

[2] This technique works, because even though the variable containing the hashtable is defined in the parent scope, the child scope can access its value and modify the entries of the referenced hashtable object rather than the variable itself.

Sign up to request clarification or add additional context in comments.

6 Comments

Well, I was about to ask exactly this but I see you already updated your answer. I understand that the child scope can see the value of the parent's scope variable and normally it would not be able to update it's value, but why or how is it possible that the child's scope (when using a hashtable) can update the value of a hashtable Key and even add/remove Keys? If it's too much hassle answering here I can definitely ask a new question but I would much appreciate to understand why does this work.
@SantiagoSquarzon, footnote [2] is meant to answer your question - I'm happy to improve it if you tell me where it falls short. Note the distinction between a variable object and the object it references.
Yes, the footnote explains that it (child scope) can modify it's members but why it is able to do that?
@SantiagoSquarzon, descendent scopes can get the value of variables in an ancestral scope. If the value of such a variable is a mutable object - such as a hashtable - modifying that object also surfaces in the variable (value) in the ancestral scope.
You're welcome, @SantiagoSquarzon. The value-type vs. reference-type dichotomy is a good rule of thumb: value types typically are immutable, as officially recommended, but technically they can be mutable.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.