【问题标题】:Implementing a custom sort for WinForms ListView为 WinForms ListView 实现自定义排序
【发布时间】:2009-07-15 00:19:48
【问题描述】:

我有一个名为Picture 的类,它有一个名称和size (int) 属性。

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

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

this.PicList.ListViewItemSorter = AllPictures[0];

this.PicList.ListViewItemSorter = Picture;

他们不编译。

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

【问题讨论】:

  • 图片是一种类型?你需要给它一个图片的实例,而不是类型。什么错误?
  • 是的,它是一个结构体。错误是无法将图片转换为 IComparer。在 #1 中,我传递了一个不起作用的图片实例。
  • 为什么有人反对它?这是一个有效的问题。

标签: c# .net winforms listview


【解决方案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

【讨论】:

  • 谢谢。这就是我需要的。这让我意识到排序不应该是图片类型的一部分。我认为它使用的是图片类型,而不是 ListViewItem。现在很清楚了。
【解决方案2】:

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

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; }
    }
}

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 是的。我完全同意。我只是向他展示了一个实现以及为什么他的不起作用。但我同意应该在列标题上完成。
    猜你喜欢
    • 2016-09-18
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多