CustomDataGridViewColumn与DataGridViewTextBoxColumn具有自定义排序

时间:2015-03-19 16:46:21

标签: c# sorting datagridview datagridviewcolumn

您好我目前有一个DataGridView,其中第一列包含一个人的名字,直到现在我已经手动将值设置为表示Person对象的字符串。其余列包含其他类/字符串。

我一直在尝试将此人分配到单元格值,以便更容易找到附加到该单元格的人。我将ToString()方法添加到Person类中,一切运行良好,直到我尝试使用

对列进行排序
_dataGridView.Sort(_dataGridView.Columns[0], ListSortDirection.Ascending);

我得到一个ArgumentException,说Object必须是String类型(我正在使用文本框列)

我已经尝试实现自己的排序方法,但是将单元格值转换为Person(表示无法将字符串转换为person)时出现问题,即使我将Person指定为值。

public void _rotaView_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
    {
        Person a = (Person)e.CellValue1;
        Person b = (Person)e.CellValue2;

        e.SortResult = a.CompareTo(b);
        e.Handled = true;
    }

无法将“System.String”类型的对象强制转换为“RotaManagerSolution.Person”。

那么关于如何将自定义类存储在datagridview单元格值中并仍能对其进行排序的任何想法?

2 个答案:

答案 0 :(得分:0)

更新

我已根据您对您的要求的理解更新了示例代码。

您可以混合使用动态对象和Sortable BindingList来实现目标。

请说这些是您的实体:

class Company
{
    public string Name { get; set; }
    public Person Contact { get; set; }
    public Address HQAddress { get; set; }
}

class Address
{
    public string City { get; set; }
    public string Country { get; set; }
}

// Define other methods and classes here
class Person
{
   public string Name { get; set; }
   public DateTime DOB { get; set; }
   public int Height { get; set; }
   public float Weight { get; set; }
}

这是您的数据:

Person p1 = new Person() { Name = "Hari", DOB = new DateTime(1781, 4, 3), Height = 165, Weight = 60.0f};
Person p2 = new Person() { Name = "Nil", DOB = new DateTime(1781, 4, 3), Height = 165, Weight = 60.0f};

Company c = new Company()
{
    Name = "Sahaj Technologies",
    Contact = p1,
    HQAddress = new Address() { City = "Sarang", Country = "India" }
};

然后您可以使用以下代码填充网格。请注意,它正在使用来自不同实体的数据。实际上,由于使用了动态对象,因此数据的来源并不重要。

dgv.DataSource = GetSortableBindingList(
    new[] {
        new { CompanyName = c.Name, ContactPerson = c.Contact.Name, HQ = c.HQAddress.City + ", " + c.HQAddress.Country},
        new { CompanyName = "Akshar Inc.", ContactPerson = p2.Name, HQ = "LA, USA"}
    }
);
// Wrapper method to allow dynamic objects
public object GetSortableBindingList<T>(IEnumerable<T> collection) where T : class
{
    return new ObservableCollection<T>(collection).ToBindingList();
}

以下是工作演示的链接: http://share.linqpad.net/5257ki.linq

P.S。要运行此演示,您需要执行以下步骤:

  1. 下载LINQPad
  2. 获取EntityFramework.dll。按照herehere
  3. 所示的说明操作
  4. 提取LINQPad,将EntityFramework.dll复制到与LINQPad.exe相同的文件夹中
  5. 下载demo文件,使用LINQPad打开它并点击F5。

答案 1 :(得分:-1)

我发现我的问题的解决方案是通过执行以下操作将自定义可排序列表数据绑定到DataGridView

创建第一列,其data属性设置为Name类的Person属性

// Add column for names (people and shifts)
DataGridViewColumn names = new DataGridViewTextBoxColumn();
names.DataPropertyName = "Name";
names.DefaultCellStyle.BackColor = System.Drawing.Color.Azure;
names.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
names.SortMode = DataGridViewColumnSortMode.NotSortable;
_rotaView.Columns.Add(names);

然后添加了here

这个自定义可排序绑定列表

绑定数据

 SortableBindingList<Person> sblist = new SortableBindingList<Person>();

 foreach (Person p in _mainManager.ListOfPeople)
 {
     sblist.Add(p);
 }
 _rotaView.DataSource = sblist;

这允许我调用此行来对列表进行排序

_rotaView.Sort(_rotaView.Columns[0], System.ComponentModel.ListSortDirection.Ascending);