为WinForms ListView实现自定义排序

时间:2009-07-15 00:19:49

标签: c# .net winforms listview

我有一个名为Picture的课程,其名称和sizeint)属性。

我打算使用尺寸对它们进行排序,但不是显示的文件名,即listview中的项目名称。

我为IComparer<Picture>类型实施了Picture,然后当我写这个时:

this.PicList.ListViewItemSorter = AllPictures[0];

this.PicList.ListViewItemSorter = Picture;

他们不编译。

我该怎么做?在MSDN上,它为分拣机显示了一个单独的类,但是我可以使用所使用的类型Picture内置吗?

3 个答案:

答案 0 :(得分:1)

你需要给它一个Picture类的实际实例,而不是类型。此外,ListViewItemSorter实际上会通过传递ListViewItem而不是Picture类来调用Comparer,您可以将Picture类的实例添加到ListViewItem的Tag属性。

像这样的东西,这是一个非常粗略的实现,只是为了给你一个想法。您可以实现自己的错误处理。

Picture test1 = new Picture() { Name = "Picture #1", Size = 54 };
Picture test2 = new Picture() { Name = "Picture #2", Size = 10 };

this.listView1.ListViewItemSorter = test1;

this.listView1.Items.Add(new ListViewItem(test1.Name) { Tag = test1 });
this.listView1.Items.Add(new ListViewItem(test2.Name) { Tag = test2 });

 public class Picture : IComparer
    {
        public string Name { get; set; }
        public int Size { get; set; }

        #region IComparer Members

        public int Compare(object x, object y)
        {
            Picture itemA = ((ListViewItem)x).Tag as Picture;
            Picture itemB = ((ListViewItem)y).Tag as Picture;

            if (itemA.Size < itemB.Size)
                return -1;

            if (itemA.Size > itemB.Size)
                return 1;

            if (itemA.Size == itemB.Size)
                return 0;

            return 0;

        }

输出结果为:

  • 图片#2
  • 图片#1

这是MSDN Link

答案 1 :(得分:1)

您可以尝试的另一个实现是将每个ListViewItem索引与存储在Dictionary<int, Picture>实例中的自定义类/结构实例相关联。您的自定义列表视图排序器类可以这样编写,如下所示:

public partial class Form1 : Form
{
    public Form1()
    {
        ...

        ListView lv = new ListView();
        lv.ListViewItemSorter = new MyCustomSorter(this);
    }

    private Dictionary<int, Picture> _pictures = new Dictionary<int,Picture>();

    private class MyCustomSorter : IComparer
    {
        private Form1 _parent;

        internal MyCustomSorter(Form1 form)
        {
            _parent = form;
        }

        #region IComparer Members

        public int Compare(object x, object y)
        {
            ListViewItem item1 = x as ListViewItem;
            ListViewItem item2 = y as ListViewItem;

            if (x != null)
            {
                if (y != null)
                {
                    Picture p1 = _parent._pictures[item1.Index];
                    Picture p2 = _parent._pictures[item2.Index];

                    return string.Compare(p1.Location, p2.Location);
                }

                // X is deemed "greater than" y
                return 1;
            }
            else if (y != null)
                return -1;      // x is "less than" y

            return 0;
        }

        #endregion
    }
}

public class Picture
{
    private string _location;

    public string Location{
        get { return _location; }
    }
}

答案 2 :(得分:1)

Stan的解决方案可行,但是,代表您的用户,我强烈建议您不要对排序顺序进行硬编码。在ListView上,每个人都希望能够通过单击标题进行排序。

ObjectListView(.NET WinForms ListView的开源包装器)免费提供点击式点击功能。如果您愿意,它甚至可以在自己的列中显示图片的缩略图。