winformspowershelldynamic-variables

How to build dynamic link list with powershell and WPF?


I have an array of variable length with several website names und corresponding links. I will show them up in a Windows Forms based GUI.

The array will be read from an XML file, but it looks like this

$linklist = @(
("Site 1" , "https://link1.com"),
("Site 2" , "https://link2.com")
)

Then i have a Windows Forms window named "mainform" and create each item in there:

$Link1 = New-Object System.Windows.Forms.LinkLabel
$Link1.Text = $sitename
$Link1.Location = New-Object System.Drawing.Point(40,$calculatedPosition)
$Link1.add_Click({ start $sitelink })
$mainform.Controls.Add($Link1)

That could be done manually for each item in my array - so far, so easy, as log i have a fixed amount of items in my array.

But i like to do it dynamically, to handle arrays with customized content.

I tried to use dynamic variables, because every LinkLabel needs a different variable name. I know, Dynamic variable names can be created by the New-Variable Cmdlet, but i have no idea, how manage this new variable for building a LinkLabel.

Thank you in advance for all your helpful ideas...


Solution

  • I would first create an ordered Hashtable out of your $linklist array-of-arrays to make things easier:

    $linklist = @(
    ("Site 1" , "https://link1.com"),
    ("Site 2" , "https://link2.com")
    )
    
    # convert the array of arrays into an ordered Hashtable
    $linkHash = [ordered]@{}
    $linklist | ForEach-Object { $linkHash[$_[0]] = $_[1] }
    

    Using that hashtable, creating the linklabels dynamically is not very hard to do:

    $linkHash.GetEnumerator() | ForEach-Object {
        $lnk = New-Object System.Windows.Forms.LinkLabel
        $lnk.Text = $_.Name   # set the name for the label
        $lnk.Tag  = $_.Value  # store the link url inside the control's Tag property
        $lnk.Location = New-Object System.Drawing.Point(40, $calculatedPosition)
        # inside the scriptblock, $this refers to the LinkLabel control itself
        $lnk.Add_Click({ Start-Process $this.Tag })  
        $mainform.Controls.Add($lnk)
        $calculatedPosition += 15   # just a guess, you may want different vertical spacing
    }