1

Is it possible to add data to a listview after a certain variable contains data ?

I have a function, which gets info from ConfigMgr when I press on a button.

After I press on that button, some info will be stored in a variable called $Results. I want the winform listview to wait until the variable $Results contains data, and then load my function, that will add data to my listview - is that possible ?

It's working fine if I don't clear the variable $Results, and run the winform a second time, because then the variable $Results is not empty, by having$Form.Add_Shown( { $Form.Activate(); Results }) in my script

Is there an equivalent method to achieve what I want ?

This is my function:

Function Get-SKUNotExists {

#Get objects stored in $Results
$listview_NotExists_SKU_Results = $Results | Select-Object Name,ID



# Compile a list of the properties 
$listview_NotExists_SKU_Properties = $listview_NotExists_SKU_Results[0].psObject.Properties

# Create a column in the listView for each property
$listview_NotExists_SKU_Properties | ForEach-Object {
    $listview_NotExists_SKU.Columns.Add("$($_.Name)") 
}

# Looping through each object in the array, and add a row for each
ForEach ($listview_NotExists_SKU_Result in $listview_NotExists_SKU_Results) {

    # Create a listViewItem, and assign it it's first value
    $listview_NotExists_SKU_Item = New-Object System.Windows.Forms.ListViewItem($listview_NotExists_SKU_Result.Name)

    # For each properties, except for 'Id' that we've already used to create the ListViewItem,
    # find the column name, and extract the data for that property on the current object/Tasksequence
    $listview_NotExists_SKU_Result.psObject.Properties | Where-Object { $_.Name -ne "ID" } | ForEach-Object {
        $listview_NotExists_SKU_Item.SubItems.Add("$($listview_NotExists_SKU_Result.$($_.Name))") 
    }

    # Add the created listViewItem to the ListView control
    # (not adding 'Out-Null' at the end of the line will result in numbers outputred to the console)
    $listview_NotExists_SKU.items.Add($listview_NotExists_SKU_Item) 
}

# Resize all columns of the listView to fit their contents
$listview_NotExists_SKU.AutoResizeColumns("HeaderSize")

}

This is the button that generate data to $results:

# Adding another button control to Form
$button_whatif = New-Object System.Windows.Forms.Button
$button_whatif.Location = New-Object System.Drawing.Size(352, 954)
$button_whatif.Size = New-Object System.Drawing.Size(320, 32)
$button_whatif.TextAlign = "MiddleCenter"
$button_whatif.Text = “WhatIf”
$button_whatif.Add_Click( { $script:Results = Set-DynamicVariables -Manufacturer "$($listview_Vendor.SelectedItems)" -TSPackageID "$($ListView_Tasksequences.SelectedItems.SubItems[1].Text)" -WhatIf })
$Form.Controls.Add($button_whatif)
BenDK
  • 131
  • 2
  • 7

1 Answers1

0

Simply call your list-populating function (Get-SKUNotExists) directly after assigning to $Results:

$button_whatif.Add_Click({ 
  $Results = Set-DynamicVariables -Manufacturer "$($listview_Vendor.SelectedItems)" -TSPackageID "$($ListView_Tasksequences.SelectedItems.SubItems[1].Text)" -WhatIf
  Get-SKUNotExists 
})

Note that I've removed the $scipt: scope specifier from $Results, since it is no longer needed, given that you're calling Get-SKUNotExists from the same scope, which means that the child scope that Get-SKUNotExists runs in implicitly sees it.

That said:

  • In general, if a value is directly available, it's more robust to pass it as a parameter (argument) rather than relying on PowerShell's dynamic scoping (where descendant scopes implicitly see variables from ancestral scopes, unless shadowed by local variables).

  • If values must be shared between multiple event handlers, storing them in the script scope ($script:...), or, more generally, the parent scope may be needed, after all - see this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775