Loading Data from .csv into DataGridView Form

Advertisements

I am trying to load the contents of a .csv table into a DataGridView. In the following code it is loaded at two point with the same method: after a button press and in the main routine.
The one in the main routine works, but the button doesn’t work.
(The DataGrid just goes blank after pressing the button, so it apprears it’s not a scope issue).

#############################################
#Functions
#############################################

function SelectCsvFile () {
    Add-Type -AssemblyName System.Windows.Forms
    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.Title = "Datei auswählen"
    $OpenFileDialog.InitialDirectory = Get-Location
    $OpenFileDialog.filter = 'Tabelle (*.csv)|*.csv'
    $SelectedFile=$OpenFileDialog.ShowDialog()
    If ($SelectedFile -eq "Cancel") {
        $result = $null
    } 
    else { 
        $result= new-object System.Collections.ArrayList
        $data=@(import-csv  $OpenFileDialog.FileName -Delimiter $ListImportDelimiter)
        $result.AddRange($data) 
    }
   
    $OpenFileDialog.Dispose()
    return $result
    
}
#############################################
#Main Routine
#############################################

# Init PowerShell Gui
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
# Create a new form
$ManageTeamsForm = New-Object system.Windows.Forms.Form
# Define the size, title and background color
$ManageTeamsForm.ClientSize = New-Object System.Drawing.Point(1000,700)


#DataGrid
$DataGrid = new-object System.windows.forms.DataGridView
$DataGrid.width             = 800
$DataGrid.height            = 500
$DataGrid.location          = New-Object System.Drawing.Point(37,80)

#loades testing csv on startup
$result= new-object System.Collections.ArrayList 
$data=@(import-csv  "./testfile.csv" -Delimiter $ListImportDelimiter)
$result.AddRange($data) 

$DataGrid.DataSource = $result


#Select File Button
$SelectCsvFileButton = New-Object System.Windows.Forms.Button
$SelectCsvFileButton.Location = New-Object System.Drawing.Size(100,35)
$SelectCsvFileButton.Size = New-Object System.Drawing.Size(120,23)
$SelectCsvFileButton.Text = "Open CSV"
$SelectCsvFileButton.Add_Click({
    $DataGrid.DataSource =SelectCsvFile;
    ForEach ($row in $DataGrid.DataSource ){ #Testing if DataSource successfully changes
        write-host $row
    }
    })

$ManageTeamsForm.controls.AddRange(@($SelectCsvFileButton,$DataGrid))
[void]$ManageTeamsForm.ShowDialog()


>Solution :

Your code is correct the only issue is that the output from your function SelectCsvFile is being enumerated, your function is no longer outputting an ArrayList but an object[] or a single object PSCumstomObject.

This is more or less explained in about Script Blocks:

A script block returns the output of all the commands in the script block, either as a single object or as an array.

You can overcome this by using the comma operator , which will wrap your ArrayList in a single element array to avoid losing the output type.

To put it into perspective with a simple example:

(& { [System.Collections.ArrayList]@(0..10) }).GetType()   # Object[]
(& { , [System.Collections.ArrayList]@(0..10) }).GetType() # ArrayList

So, changing your function as follows should solve your problem:

function SelectCsvFile {
    $fileDialog = [System.Windows.Forms.OpenFileDialog]@{
        Title            = "Datei auswählen"
        InitialDirectory = Get-Location
        Filter           = 'Tabelle (*.csv)|*.csv'
    }

    if($fileDialog.ShowDialog() -eq 'OK') {
        , [System.Collections.ArrayList]@(Import-Csv $fileDialog.FileName -Delimiter $ListImportDelimiter)
    }
}

Leave a ReplyCancel reply