Forms 使用Powershell表单中的整数值对Listview控件列进行排序

Forms 使用Powershell表单中的整数值对Listview控件列进行排序,forms,powershell,listview,type-conversion,columnsorting,Forms,Powershell,Listview,Type Conversion,Columnsorting,我试图在下面的Listview中对列“大小(kb)”进行排序。“大小(kb)”列将根据不是预期结果的文本值进行排序。我得到了所有其他列的正确结果 # Defining the listbox fo displaying the search results $lvw_resultsListView = New-Object System.Windows.Forms.ListView -Property @{ View = [System.Windows.Forms.View

我试图在下面的Listview中对列“大小(kb)”进行排序。“大小(kb)”列将根据不是预期结果的文本值进行排序。我得到了所有其他列的正确结果

# Defining the listbox fo displaying the search results
$lvw_resultsListView = New-Object System.Windows.Forms.ListView -Property @{
    View        = [System.Windows.Forms.View]::Details
    Location    = New-Object System.Drawing.Size(10, 40)  
    Width       = 700
    Height      = 350
    Scrollable  = $true
    MultiSelect = $true
    Font        = 'Arial,10'
    AutoSize    = $true
    Sorting     = "Ascending"
    FullRowSelect = $true
    GridLines = $True
}
下面是向Listview添加列的代码

# Adding Columns to List View
$lvw_resultsListView.columns.Add("Filename", 150) | Out-Null
$lvw_resultsListView.columns.Add("Path", 340) | Out-Null
$lvw_resultsListView.columns.Add("Size (kb)", 90) | Out-Null
$lvw_resultsListView.columns.Add("Created on", 70) | Out-Null
$lvw_resultsListView.columns.Add("Ext", 60) | Out-Null
下面是从文件对象添加值的代码

# Clearing list view items
$lvw_resultsListView.Items.Clear()
# Adding file information to the list bx by cycling through each file
foreach ($file in $global:files) {
    $fileItem = New-Object System.Windows.Forms.ListViewItem( $file.BaseName)
    $fileItem.Subitems.Add($file.FullName) | Out-Null
    $fileItem.Subitems.Add($file.Length) | Out-Null
    $tempCreationDate = $file.CreationTime | Get-Date -f "yyyy-MM-dd"
    $fileItem.Subitems.Add($tempCreationDate) | Out-Null
    $fileItem.Subitems.Add($file.Extension) | Out-Null
    $lvw_resultsListView.Items.Add($fileItem) | Out-Null
}
这是在单击列时调用的排序函数

function SortListView {
    Param(
        [System.Windows.Forms.ListView] $senderPsItem,
        $column
    )
    $temp = $senderPsItem.Items | Foreach-Object { $_ }
    $Script:SortingDescending = !$Script:SortingDescending
    $senderPsItem.Items.Clear()
    $senderPsItem.ShowGroups = $false
    $senderPsItem.Sorting = 'none'
    
    if($column.Text -eq "Size (kb)") {
        
        $senderPsItem.Items.AddRange(($temp | Sort-Object -Descending:$script:SortingDescending -Property @{ Expression={ [int]$_.SubItems[$column].Text } }))
        
    } else {
        $senderPsItem.Items.AddRange(($temp | Sort-Object -Descending:$script:SortingDescending -Property @{ Expression={ $_.SubItems[$column].Text } }))

    }
}
这里(来自结果表单的片段)是我在“大小(kb)”列中得到的一个示例结果

下面是代码调用排序函数

$lvw_resultsListView.Add_ColumnClick({SortListView $this $_.Column})
是否有人可以建议一种改进我的排序函数的方法,以正确地对整型列进行排序。我尝试使用[int]方法将测试转换为整数,这可以从排序函数中看出?
提前谢谢你

检查列“大小(kb)”的IF条件不正确。列索引用于修复此问题

改变

如果($column.Text-eq“大小(kb)”)

如果($列-等式2)

我更新了排序函数以更正IF条件

function SortListView {
    Param(
        [System.Windows.Forms.ListView] $senderPsItem,
        $column
    )
    $temp = $senderPsItem.Items | Foreach-Object { $_ }
    $Script:SortingDescending = !$Script:SortingDescending
    $senderPsItem.Items.Clear()
    $senderPsItem.ShowGroups = $false
    $senderPsItem.Sorting = 'none'
    Write-Host $column
    
    if($column -eq 2) {
        
        $senderPsItem.Items.AddRange(($temp | Sort-Object -Descending:$script:SortingDescending -Property @{ Expression={ [int]$_.SubItems[$column].Text } }))
        
    } else {
        $senderPsItem.Items.AddRange(($temp | Sort-Object -Descending:$script:SortingDescending -Property @{ Expression={ $_.SubItems[$column].Text } }))

    }
}

这为整数列提供了正确的结果。

在这里,尝试一下这段代码,它将帮助您理解为什么我提到了
DataGridView
DataTable
,这对我个人在使用WPF时产生了很大的影响

尝试对
*时间
长度
列进行排序,您将了解原因:)


在变量赋值下方放置一个
Write Host$temp
,然后单击要排序的列,这将有助于理解函数不工作的原因。建议您使用
DataTable
作为数据源查看
DataGridView
。编写代码会容易得多。哇!这真的很有帮助。谢谢圣地亚哥!
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName PresentationFramework

$myFont='Helvetica'

$mainForm=New-Object System.Windows.Forms.Form
$mainForm.StartPosition='CenterScreen'
$mainForm.Icon=[System.Drawing.Icon]::ExtractAssociatedIcon("$PSHOME\PowerShell.exe")
$mainForm.KeyPreview=$True
$mainForm.FormBorderStyle='Fixed3D'
$mainForm.Text='Test'
$mainForm.WindowState='Maximized'

$bounds=($mainForm.CreateGraphics()).VisibleClipBounds.Size

$dataGrid=New-Object System.Windows.Forms.DataGridView
$dataGrid.Size=New-Object System.Drawing.Size(($bounds.Width-20),$($bounds.Height-140))
$dataGrid.Location=New-Object System.Drawing.Size(10,60)
$dataGrid.Font=New-Object System.Drawing.Font($myFont,9,[System.Drawing.FontStyle]::Regular)
$dataGrid.DefaultCellStyle.WrapMode='True'
$dataGrid.AllowUserToAddRows=$false
$dataGrid.SelectionMode=0
$dataGrid.MultiSelect=$True
$dataGrid.ReadOnly=$false
$dataGrid.EnableHeadersVisualStyles=$True
$datagrid.Anchor='Top, Bottom, Left'
$mainForm.Controls.Add($dataGrid)

#Here goes your Data Source
$dataSource = Get-ChildItem "$HOME\Documents" -File|select Name,Length,LastWriteTime,CreationTime

$columns=$dataSource[0].PSobject.Properties.Name
$table = New-Object system.Data.DataTable

foreach($column in $columns)
{
    $type=switch -Wildcard($column)
    {
        'Length'{[int]}
        '*Time'{[datetime]}
        Default{[string]}
    }

    $i = New-Object System.Data.DataColumn
    $i.DataType = $type
    $i.ColumnName = $column
    $table.Columns.Add($i)
}

foreach($line in $dataSource)
{
    $row = $table.NewRow()
    
    foreach($column in $columns)
    {
        $row.$column = $line.$column
    }

    $table.Rows.Add($row)
}

# Here you bind your DataSource to your DataGridView
$dataGrid.DataSource=$table

$dataGrid.RowHeadersVisible=$false
$dataGrid.ColumnHeadersBorderStyle=2
$dataGrid.AutoSizeColumnsMode=[System.Windows.Forms.DataGridViewAutoSizeColumnMode]::AllCells
$dataGrid.ColumnHeadersHeight=25

$sum=0
$dataGrid.Columns.Width|%{$sum+=$_}

if($sum -lt $dataGrid.Width)
{
    $dataGrid.Columns[-1].AutoSizeMode=[System.Windows.Forms.DataGridViewAutoSizeColumnMode]::Fill
}


$mainForm.ShowDialog()