Home > OS >  Powershell Forms - retrieve both values and column names from selected ListView item
Powershell Forms - retrieve both values and column names from selected ListView item

Time:11-27

I have a working script using Powershell forms and and for convenience I'm retrieving the value from the currently selected item in a listview and copying them to clipboard as follows:

$UIDlist.Add_SelectedIndexChanged({
    # Legacy Winforms behaviour can cause an error unless a null check is made
    If($UIDlist.SelectedItems -ne $null) {
        [string]$ClipText = $this.SelectedItems.SubItems.Text | ForEach-Object{$_   "`r`n"}
        $ClipText | Set-Clipboard
})

Obviously this only outputs the text values of the subitems e.g.

johnsmith01
johnsmith@company.com
\\myserver\johnsmith01
GPO Main Office

Is there an easy way to also get the column names for those values? e.g.

SamAccountName johnsmith01
EmailAddress   johnsmith@company.com
HomeDrive      \\myserver\johnsmith01
DepoartmentGPO GPO Main Office

There seems to be a Name property of ListView subiteems but I couldnt find the method to populate that when constructing the ListView:

BackColor : Color [Window]
Bounds    : {X=0,Y=0,Width=0,Height=0}
Font      : [Font: Name=Microsoft Sans Serif, Size=8.25, Units=3, GdiCharSet=0, GdiVerticalFont=False]
ForeColor : Color [WindowText]
Tag       : 
Text      : johnsmith01
Name      :

So is there an easy way to retrieve values and the column names for those values when selecting a ListView item?

CodePudding user response:

The name of the listview item is not the column name. It is there in case you want to differentiate what you present to the user (text) and the actual value you will work it behind the scene.

To get the column name, you need to make your own solution. Here is something that would work.

To be declared somewhere before the Add_SelectedIndexChangedMethod so it doesn't get called every time for nothing.

$ColumnsName = $ListView.Columns.Text
# Used for padded formatting
$LongestColLength = ($ColumnsName | % { $_.length } | Measure-Object -Maximum ).Maximum   1
$ListView.Items[0].SubItems.text

And the actual $ClipText section

$ClipText = for ($i = 0; $i -lt $ColumnsName.Count  ;$i  ) {
    "{0}: {1} `r`n" -f $ColumnsName[$i].PadRight($LongestColLength, ' '), $this.SelectedItems.SubItems[$i].Text
} 

Output

output

Based on your code, I assumed you wanted to send it to the clipboard immediately with a pretty format but if that is not necessarily the case, I would instead produce a PSObject of what you want so that you can do additional manipulation with ease.

$ClipText = for ($i = 0; $i -lt $ColumnsName.Count  ;$i  ) {
[PSCustomObject]@{
        ColumnName = $ColumnsName[$i]
        Text       = $this.SelectedItems.SubItems[$i].Text
    }
}

Whenever ready, you can still convert your newly formed PSObject to its final format.

User friendly (making use of the longest column length for padding)

$ClipText | % { '{0}: {1}' -f $_.ColumnName.PadRight($LongestColLength,' '),$_.Text}

Machine friendly

$ClipText | ConvertTo-Json

CodePudding user response:

Answer as in Sage's post. In my case I needed the add the following to get the clipboard formatting and output correct:

    [string]$ClipText = for ($i = 0; $i -lt $ColumnsName.Count  ;$i  ) {
        '{0}: {1}' -f $ColumnsName[$i].PadRight($LongestColLength, ' '), $this.SelectedItems.SubItems[$i].Text   "`r`n"
    } 

Without [string] only the last object was in the clipboard and the carriage return/newline was also required

I have PSCX module installed, which modifies the Set-Clipboard command, so YMMV

  • Related