ListView排序不起作用OnClick(PowerShell)

时间:2016-03-08 15:31:39

标签: winforms sorting listview powershell

我在PowerShell中构建的表单上有一个ListView,我无法对其进行排序。

如果我从命令行调用$ LV.Sort()(虽然没有显示表单),它可以正常工作。但是,如果我尝试在OnClick事件中对表单上的任何内容调用它,它就不会。我已经放入了标记,我知道代码段正在运行,它只是没有做任何事情或标记任何错误。

显然$LV.Sorting = "Ascending"已设置,否则它根本就不会排序,我可以更改项目,以便对ListView的引用很好。如果出现线程问题,也尝试调用但没有区别。

令人讨厌的是,由于很多人忘记设置排序属性,这是一个棘手的研究课题。

编辑:不确定是否相关但是使用ShowDialog()

调用表单
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$form = New-Object System.Windows.Forms.Form
$LVserverlist = New-Object System.Windows.Forms.ListView
$form.Controls.Add($LVserverlist)
    $LVserverlist.Dock = "Fill"
    $LVserverlist.View = "Details"
    $LVserverlist.Sorting = "Ascending"
    $LVserverlist.Add_ColumnClick({ $LVserverlist.sort(); $LVserverlist.Items[0].Text = "Working?" })
    $LVserverlist.Columns.Add("Name", 200, "Left") | Out-Null

0..10 | Foreach-Object {
    $LVItem = New-Object System.Windows.Forms.ListViewItem
    $LVItem.Text = (Get-Random -Maximum 1000).ToString()
    $LVserverlist.Items.Add($LVItem) | Out-Null
}

$form.ShowDialog()

3 个答案:

答案 0 :(得分:1)

从来没有找到让Sort()工作的解决方案,最终得到了这种解决方法(无论如何都更灵活):

Param
(
    [System.Windows.Forms.ListView]$sender,
    $column
)
$temp = $sender.Items | Foreach-Object { $_ }

$sender.Items.Clear()
$sender.Items.AddRange(($temp | Sort-Object -Property @{ Expression={ $_.SubItems[$column].Text } }))

请注意,在ListView上,Sorting属性需要设置为None,否则将按字母顺序添加项目。

答案 1 :(得分:0)

coller事件

$MyListView.add_ColumnClick({SortListView $this $_.Column})

排序功能白衣记忆最新订单:

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

答案 2 :(得分:0)

您可以尝试使用自定义功能Sort-ListViewColumn

$MyListView.Add_ColumnClick({
    param($sender,$e)
    # Sort as Text String (not [int])
    Sort-ListViewColumn -ListView $this -ColumnIndex $e.column
})

全功能代码:

function Sort-ListViewColumn
{
    <#
    .SYNOPSIS
        Sort the ListView's item using the specified column.
    .DESCRIPTION
        Sort the ListView's item using the specified column.
        This function uses Add-Type to define a class that sort the items.
        The ListView's Tag property is used to keep track of the sorting.
    .PARAMETER ListView
        The ListView control to sort.
    .PARAMETER ColumnIndex
        The index of the column to use for sorting.

    .PARAMETER  SortOrder
        The direction to sort the items. If not specified or set to None, it will toggle.

    .EXAMPLE
        Sort-ListViewColumn -ListView $listview1 -ColumnIndex 0

    .NOTES
        SAPIEN Technologies, Inc.
        http://www.sapien.com/

#>
    param (
        [ValidateNotNull()]
        [Parameter(Mandatory = $true)]
        [System.Windows.Forms.ListView]$ListView,
        [Parameter(Mandatory = $true)]
        [int]$ColumnIndex,
        [System.Windows.Forms.SortOrder]$SortOrder = 'None')

    if (($ListView.Items.Count -eq 0) -or ($ColumnIndex -lt 0) -or ($ColumnIndex -ge $ListView.Columns.Count))
    {
        return;
    }

    #region Define ListViewItemComparer
    try
    {
        $local:type = [ListViewItemComparer]
    }
    catch
    {
        Add-Type -ReferencedAssemblies ('System.Windows.Forms') -TypeDefinition  @" 
    using System;
    using System.Windows.Forms;
    using System.Collections;
    public class ListViewItemComparer : IComparer
    {
        public int column;
        public SortOrder sortOrder;
        public ListViewItemComparer()
        {
            column = 0;
            sortOrder = SortOrder.Ascending;
        }
        public ListViewItemComparer(int column, SortOrder sort)
        {
            this.column = column;
            sortOrder = sort;
        }
        public int Compare(object x, object y)
        {
            if(column >= ((ListViewItem)x).SubItems.Count)
                return  sortOrder == SortOrder.Ascending ? -1 : 1;

            if(column >= ((ListViewItem)y).SubItems.Count)
                return sortOrder == SortOrder.Ascending ? 1 : -1;

            if(sortOrder == SortOrder.Ascending)
                return String.Compare(((ListViewItem)x).SubItems[column].Text, ((ListViewItem)y).SubItems[column].Text);
            else
                return String.Compare(((ListViewItem)y).SubItems[column].Text, ((ListViewItem)x).SubItems[column].Text);
        }
    }
"@ | Out-Null
    }
    #endregion

    if ($ListView.Tag -is [ListViewItemComparer])
    {
        #Toggle the Sort Order
        if ($SortOrder -eq [System.Windows.Forms.SortOrder]::None)
        {
            if ($ListView.Tag.column -eq $ColumnIndex -and $ListView.Tag.sortOrder -eq 'Ascending')
            {
                $ListView.Tag.sortOrder = 'Descending'
            }
            else
            {
                $ListView.Tag.sortOrder = 'Ascending'
            }
        }
        else
        {
            $ListView.Tag.sortOrder = $SortOrder
        }

        $ListView.Tag.column = $ColumnIndex
        $ListView.Sort()#Sort the items
    }
    else
    {
        if ($Sort -eq [System.Windows.Forms.SortOrder]::None)
        {
            $Sort = [System.Windows.Forms.SortOrder]::Ascending
        }

        #Set to Tag because for some reason in PowerShell ListViewItemSorter prop returns null
        $ListView.Tag = New-Object ListViewItemComparer ($ColumnIndex, $SortOrder)
        $ListView.ListViewItemSorter = $ListView.Tag #Automatically sorts
    }
}