Winform | Listview Item skips the first object in array

Welcome Forums General PowerShell Q&A Winform | Listview Item skips the first object in array

This topic contains 5 replies, has 2 voices, and was last updated by

 
Participant
1 week, 1 day ago.

  • Author
    Posts
  • #172948

    Participant
    Topics: 1
    Replies: 2
    Points: 16
    Rank: Member

    List view item pushes the contents on my array one step, how can I come around this ? I read that List view Items creates the first content in listview.text, but I cant figure out how to incorporate that in my code

    Function Get-Result {
    
    #Get objects stored in $Results
    $listview_NotExists_SKU_Results = $Results  
    
    # 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)
    
        # find the column name, and extract the data for that property on the current object/Tasksequence
        $listview_NotExists_SKU_Result.psObject.Properties |  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")
    }
  • #172993

    Participant
    Topics: 1
    Replies: 2
    Points: 16
    Rank: Member

    Figured it out, the variable did not contain any objects called .name..

     

  • #173026

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    Ben,

    Great work on figuring out the issue. I'm interested in understanding the code a bit more. Some recommended best practices are below.

    1. Use the ForEach loop every time and never Foreach-Object when building a script. You will thank me later on. 🙂
    2. When creating the variable for a Foreach loop use a different variable than the singular version of the plural. This makes it very easy to accidentally tab complete the wrong variable or miss read the code.
      Foreach ($ListView-NotExists_Sku_Result in $ListView-NotExists_Sku_Results )
      1. I personally use Entry, Item, Member, Property or User. This naming standard will work 99% of the time when it doesn't try using another simple alternative. 🙂
        Foreach ($Entry in $ListView_NoExists_Sku_Results){
           $ListViewItem = New-Object -Type System.Windows.Forms.ListViewItems($Entry.Name)
           ForEach ($Property in $Entry.PsObject.Properties){
              $ListViewItem.SubItems.Add("$($Entry.$($_.Name))")
           }
           $ListView_NotExists_SKU.Items.Add($ListViewItem)
        }
  • #173071

    Participant
    Topics: 1
    Replies: 2
    Points: 16
    Rank: Member

    Thanks for the reply Jason, that does makes sense – I will do that right away.

    I just did it like that, so I would keep the names uniqe, but of course the name would be reset in another Foreach loop, if I had to reuse the name again.

    The reason you want me to use Foreach instead of Foreach-Object, is because how they are referenced right ?
    So $_.Name would be $Entry.name for easier reading right ?  wouldn't this line be $ListViewItem.SubItems.Add("$($Entry.$($Property.name ))") then ?

     

  • #173077

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    Hey Ben,

    So `$_.Name` would be `$Entry.name` for easier reading right ?  wouldn't this line be `$ListViewItem.SubItems.Add("$($Entry.$($Property.name ))")` then ?
    Answer:
    Yes, you are correct. I missed that part like I said the original code was a bit hard to parse. 😉

    When creating comments make them for other readers, not for yourself, it doesn't matter if you understand it. It only matters if another person understands the comments that you provide. 🙂 I'm dealing with that right now in an automation script that is over 4400 lines of PowerShell code from a predecessor. Very high level and vague comments. If you do the comments correctly you can then turn them into Write-Verbose when you start building Advanced Functions.

    The main reason for using Foreach Loop instead of Foreach-Object is mainly best practice when coding/scripting. The Foreach-Object is designed to allow you to pipe data to a command that may not accept the value from the pipeline and/or doesn't accept multiple values. i.e. [String] vs [String[]] from the pipeline. You are correct it does allow you to keep track of the objects easily.

    If you are using PowerShell ISE, I would highly recommend looking at switching to VisualStudio Code soon, it's free and makes it a lot easier to code in. I would recommend reading the free ebook provided by Don Jones the Big Books of PowerShell Gotchas < – Link. On the left-hand side, you will see Free Resources > eBooks > The Big Book of PowerShell Gotchas, in case you don't trust clicking on links. 🙂

     

    I also recommend picking up Learn PowerShell in a Month of Lunches and Learn PowerShell Tool Making in a Month of Lunches. I recommend buying the books on manning.com. Manning is an awesome book publisher for all programming languages.

  • #173086

    Participant
    Topics: 0
    Replies: 100
    Points: 363
    Helping Hand
    Rank: Contributor

    Well thats a drag... my whole spill just got removed... Lol

    The reason you want me to use Foreach instead of Foreach-Object, is because how they are referenced right ?
    So $_.Name would be $Entry.name for easier reading right ?  wouldn't this line be $ListViewItem.SubItems.Add("$($Entry.$($Property.name ))") then ?

    Answer: Yes, that is correct. Like I said it made the code cumbersome to read. 🙂

    When dealing with coding always use the coded method instead of the one-liner method i.e. Foreach Loop vs Foreach-Object. The Foreach-Object is meant to be used when you are doing one-liner in PowerShell command line. The fact you are taking the time to write a script means you want to use proper formatting and coding best practices. i.e Foreach instead of Foreach-Object, Tabbing in on a Foreach loop and If, Elseif, Else, Try and Catch statements, etc.

    I highly recommend reading Learn PowerShell in a Month of Lunches and then Learn PowerShell Toolmaking in a Month of Lunches. I would also recommend you to read the free ebook from Don Jones located on the left-hand side Free Resources > eBooks > The big book of PowerShell Gotchas.

    If you are interested in developing better scripts, I would recommend switching over to Visual Studio Code soon and learning about Git and GitHub. They will make your life easier and offer free versioning. If you don't know about versioning then you will. 🙂

You must be logged in to reply to this topic.