首页 > 解决方案 > 在c#中对绑定到类列表的dataGridView进行排序的优雅方法

问题描述

我的问题是找到动态排序 dataGridView 的方法,其中数据源绑定到对象列表,以如下方式调用它:

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        myList.Sort((x,y) => x.getfield(e.ColumnIndex).CompareTo(y.getfield(e.ColumnIndex)))) ;
    }

我解释我的情况。我的班级是这样定义的:

public class FileWorking
    {
        private string Host;
        private string Id;
        private string Path;
        private string Filename;
        private string Username;
        private string ModRW;
        private DateTime Starttime;
        private DateTime Endtime;
        private int Status;

        public string host { get => Host; set => Host = value; }
        public string id { get => Id; set => Id = value; }
        public string path { get => Path; set => Path = value; }
        public string filename { get => Filename; set => Filename = value; }
        public string username { get => Username; set => Username = value; }
        public string modRW { get => ModRW; set => ModRW = value; }
        public DateTime starttime { get => Starttime; set => Starttime = value; }
        public DateTime endtime { get => Endtime; set => Endtime = value; }
        public int stato {get => Stato; set => Stato=value;}
        public TimeSpan active { get => (Endtime - Starttime); }
}

然后是列表:

public List<FileWorking> historyFiles;

填充列表后,我使用 dataGridView 组件显示它:

        dataGridView1.DataSource = historyFiles;
        dataGridView1.Refresh();

现在我想按每列对 dataGridView1 进行排序。我是这样做的(因为 dataGridView1.Sort(e.ColumnIndex) 通过异常):

 private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
   switch (dataGridView1.Columns[e.ColumnIndex].HeaderText)
                {
                    case "host":
                        historyFiles.Sort((x, y) => x.host.CompareTo(y.host));
                        break;
                    case "id":
                        historyFiles.Sort((x, y) => x.id.CompareTo(y.id));
                        break;
                    case "username":
                        historyFiles.Sort((x, y) => x.username.CompareTo(y.username));
                        break;
                    case "modRW":
                        historyFiles.Sort((x, y) => x.modRW.CompareTo(y.modRW));
                        break;
                    case "starttime":
                        historyFiles.Sort((x, y) => x.starttime.CompareTo(y.starttime));
                        break;
                    case "path":
                        historyFiles.Sort((x, y) => x.path.CompareTo(y.path));
                        break;
                    case "filename":
                        historyFiles.Sort((x, y) => x.filename.CompareTo(y.filename));
                        break;
                    case "endtime":
                        historyFiles.Sort((x, y) => x.endtime.CompareTo(y.endtime));
                        break;
                    case "stato":
                        historyFiles.Sort((x,y) => x.stato.CompareTo(y.stato));
                        break;
                    case "active":
                        historyFiles.Sort((x, y) => x.active.CompareTo(y.active));
                        break;
                }

                dataGridView1.Refresh();
}

我知道这不是最好的解决方案: - 即使类型相似,每个字段也使用比较 - 如果我添加一些其他属性,我会在开关中添加特定的行......

我尝试在 FileWorking 类中实现此功能的反射:

public object getfield(int fieldindex)
        {
            Type t = this.GetType();
            PropertyInfo[] props = t.GetProperties();
            object prop =props.GetValue(fieldindex);
            return prop;

        }

但是当我尝试这样调用时,我无法编译(实际上对象没有 CompareTo,即使 int、string、DateTime、TimeSpan 是...):

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
        historyFiles.Sort((x,y) => x.getfield(e.ColumnIndex).CompareTo(y.getfield(e.ColumnIndex)))) ;
    }

有什么办法吗?

在此先感谢,菲利波

标签: listsortingcompare

解决方案


解决了,基于这个答案6942512,就这样:

    private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            var propInfo = typeof(FileWorking).GetProperty(dataGridView1.Columns[e.ColumnIndex].Name);
            Comparison<FileWorking> asc = (t1, t2) => ((IComparable)propInfo.GetValue(t1, null)).CompareTo(propInfo.GetValue(t2, null));
            historyFiles.Sort(asc);
        }

推荐阅读