为CSV数据创建可编辑的powershell GUI

时间:2015-12-02 17:26:18

标签: csv powershell datagridview powershell-studio

目标:创建一个填充了CSV数据的GUI表单,允许用户编辑数据,然后将数据保存在数组中以便进一步操作。

注意:使用PowerShell Studio生成包含CSV数据的表单

当前代码:   - 调用代码($ path从调用表单传递):

$rows = Import-Csv -Path $path
$table = ConvertTo-DataTable -InputObject $rows
Load-DataGridView -DataGridView $datagridviewResults -Item $table
  • ConvertTo-DataTable函数:
function ConvertTo-DataTable {
    
    [OutputType([System.Data.DataTable])]
    param(
        [ValidateNotNull()]
        $InputObject, 
        [ValidateNotNull()]
        [System.Data.DataTable]$Table,
        [switch]$RetainColumns,
        [switch]$FilterWMIProperties
    )

    if($Table -eq $null) {
        $Table = New-Object System.Data.DataTable
    }

    if($InputObject-is [System.Data.DataTable]) {
        $Table = $InputObject
    } else {
        if(-not $RetainColumns -or $Table.Columns.Count -eq 0) {
            #Clear out the Table Contents
            $Table.Clear()

            if($InputObject -eq $null){ return } #Empty Data

            $object = $null
            #find the first non null value
            foreach($item in $InputObject) {
                if($item -ne $null) {
                    $object = $item
                    break   
                }
            }

            if($object -eq $null) { return } #All null then empty

            #Get all the properties in order to create the columns
            foreach ($prop in $object.PSObject.Get_Properties()) {
                if(-not $FilterWMIProperties -or -not $prop.Name.StartsWith('__')) { #filter out WMI properties
                    #Get the type from the Definition string
                    $type = $null

                    if($prop.Value -ne $null) {
                        try{ $type = $prop.Value.GetType() } catch {}
                    }

                    if($type -ne $null) { # -and [System.Type]::GetTypeCode($type) -ne 'Object')
                        [void]$table.Columns.Add($prop.Name, $type) 
                    } else { #Type info not found
                        [void]$table.Columns.Add($prop.Name)    
                    }
                }
            }

            if($object -is [System.Data.DataRow]) {
                foreach($item in $InputObject) {    
                    $Table.Rows.Add($item)
                }
                return  @(,$Table)
            }
        } else {
            $Table.Rows.Clear() 
        }

        foreach($item in $InputObject) {        
            $row = $table.NewRow()

            if($item) {
                foreach ($prop in $item.PSObject.Get_Properties()) {
                    if($table.Columns.Contains($prop.Name)) {
                        $row.Item($prop.Name) = $prop.Value
                    }
                }
            }
            [void]$table.Rows.Add($row)
        }
    }

    return @(,$Table)   
}
  • Load-DataGridView功能:
function Load-DataGridView {
    
    Param (
        [ValidateNotNull()]
        [Parameter(Mandatory=$true)]
        [System.Windows.Forms.DataGridView]$DataGridView,
        [ValidateNotNull()]
        [Parameter(Mandatory=$true)]
        $Item,
        [Parameter(Mandatory=$false)]
        [string]$DataMember
    )
    $DataGridView.SuspendLayout()
    $DataGridView.DataMember = $DataMember
    $DataGridView.EditMode = 'EditOnEnter'

    if ($Item -is [System.ComponentModel.IListSource]`
    -or $Item -is [System.ComponentModel.IBindingList]`
    -or $Item -is [System.ComponentModel.IBindingListView]) {
        $DataGridView.DataSource = $Item
    } else {
        $array = New-Object System.Collections.ArrayList

        if ($Item -is [System.Collections.IList]) {
            $array.AddRange($Item)
        } else {    
            $array.Add($Item)   
        }
        $DataGridView.DataSource = $array
    }

    $DataGridView.ResumeLayout()
}

附加信息:代码正在生效,它生成网格视图并使用CSV数据填充它。但是,我无法对其进行编辑,并且需要帮助编码在编辑后捕获更改的功能。

提前致谢。

12/5编辑:在上面的“Load-DataGridView”函数中添加了“$ DataGridView.EditMode ='EditOnEnter'”。没有改变。试图在新的RowCellClick事件中调用“BeginEdit”事件,但这也不起作用。仍然在努力解决这个问题。

1 个答案:

答案 0 :(得分:0)

对于其他人,您为此感到苦恼....

set-strictmode -Version 2.0

function EditCSV($title, $Instructions, $csvPath, $x = 100, $y=100, $Width=600, $Height=400, $SaveChangesToFile=$true, $ReturnStatusOrArray='Status') { 
    #Windows Assemblies
        [reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null 
        [reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null 

    #LoadCSV
        #Variables MUST have script scope to allow form to see them
        $script:Updated = $false
        $script:CsvData = New-Object System.Collections.ArrayList 
        $script:CsvData.AddRange((import-csv $csvPath))

    #Helper Functions
       function paint($form, $ctrl, $TablIndex, $name, $Text, $x, $y, $Width, $Height){
            try{$form.Controls.Add($ctrl)                             }catch{}
            try{$ctrl.TabIndex = $TablIndex                           }catch{}
            try{$ctrl.Text     = $Text                                }catch{}
            try{$ctrl.name     = $name                                }catch{}
            try{$ctrl.Location = System_Drawing_Point $x     $y       }catch{}
            try{$ctrl.size     = System_Drawing_Size  $Width $Height  }catch{}
            try{$ctrl.DataBindings.DefaultDataSourceUpdateMode = 0    }catch{}
            $ctrl
        }
        function System_Drawing_Point($x,     $Y)     {$_ = New-Object System.Drawing.Point; $_.x     = $X;     $_.Y      = $Y;      $_}
        function System_Drawing_Size( $Width, $Height){$_ = New-Object System.Drawing.Size;  $_.Width = $Width; $_.Height = $Height; $_}

    #Paint Form
        $form1      = paint $null (New-Object System.Windows.Forms.Form) $null 'form1' $Title $x $y $Width $Height
                    $form1.add_Load({
                        $dataGrid1.DataSource = $script:CsvData; 
                        $form1.refresh() 
                    }) 
        $label1     = paint $form1 (New-Object System.Windows.Forms.Label) $null "label1" "$Instructions" 12 13 ($width-100) 23
                    $label1.Font = New-Object System.Drawing.Font("Microsoft Sans Serif",9.75,2,3,0) 
                    $label1.ForeColor = [System.Drawing.Color]::FromArgb(255,0,102,204) 
        $buttonSave = paint $form1 (New-Object System.Windows.Forms.Button) 1 "button1" "Save" ($width-200) ($Height-75) 75 23 
                    $buttonSave.UseVisualStyleBackColor = $True 
                    $buttonSave.add_Click({ 
                        $script:Updated = $true
                        $Form1.Close()
                    }) 
        $buttonClose = paint $form1 (New-Object System.Windows.Forms.Button) 2 'button2' 'Close' ($width-105) ($Height-75) 75 23 
                    $buttonClose.UseVisualStyleBackColor = $True 
                    $buttonClose.add_Click({ 
                        $Form1.Close()
                    }) 
        $dataGrid1 = paint $form1 (New-Object System.Windows.Forms.DataGrid) 0 "dataGrid0" $Null 12 40 ($width-40) ($Height-125) 
                    $dataGrid1.HeaderForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0) 

    #Show and Wait till complete
        $form1.ShowDialog()| Out-Null 

    #Save CSV
        if( $SaveChangesToFile -eq $true -and $script:Updated ){
            $script:CsvData| export-csv -NoTypeInformation -path $csvPath
        }
        if( $ReturnStatusOrArray -eq 'Status'){
            return $script:Updated
        }else{
            return $script:CsvData
        }
} 

##  Unit Test 
    cls
    function script:Indent-ConsoleOutput($output, $indent = '    '){
        if(!($output -eq $null)){
            if(!( $indent -is [string])){
                $indent = ''.PadRight($indent)
            }
            $width = (Get-Host).UI.RawUI.BufferSize.Width - $indent.length
            ($output| out-string).trim().replace( "`r", "").split("`n").trimend()| %{
                for($i=0; $i -le $_.length; $i+=$width){
                    if(($i+$width) -le $_.length){ 
                        "$indent"+$_.substring($i, $width)
                    }else{
                        "$indent"+$_.substring($i, $_.length - $i)
                    }
                }
            }
        }
    }

    Write-Host '##  Before  '.PadRight(120, '#')
        $filePath = 'C:\temp\Text.csv'
        $d = (dir c: |select-object -property Directory, Mode, LastWriteTime, Length, Name)[0..5]
        $d |export-csv -path $filePath  -NoTypeInformation
        Indent-ConsoleOutput (import-csv  $filePath |format-table) 4

    Write-Host '##  Edit - Save to File '.PadRight(120, '#')
        Indent-ConsoleOutput (EditCSV 'Example of PS Editable Grid' '[SAVE] - To Save Changes' $filePath ) 4

    Write-Host '##  After  '.PadRight(120, '#')
        Indent-ConsoleOutput (import-csv  $filePath |format-table) 4

    Write-Host '##  Edit - Return Array '.PadRight(120, '#')
        Indent-ConsoleOutput (EditCSV 'Example of PS Editable Grid' '[SAVE] - To Save Changes' $filePath -SaveChangesToFile $false -ReturnStatusOrArray 'Array'|format-table) 4
        Indent-ConsoleOutput (import-csv  $filePath |format-table) 4

享受