8

我想将 List of CourseDetails 绑定List<CourseDetails> / 。每个 CourseDetail 都有一个StudentList类型 为 的属性List<Student>。学生列表应进行旋转,以使结果如下所示:

所需数据网格布局示例

我的问题

我怎样才能使每个学生都旋转,StudentList以便我可以将 a 数据绑定List<CourseDetails>到同一个

 var courseList = List<CourseDetails>();
 courseList.Add(cd1);
 courseList.Add(cd2);

我至少有三个我无法解决的问题:

  1. 如何在 courseDetails 实例中旋转 StudentList
  2. 如何将两个 courseDetail 对象 (cd1, cd2) / 或 n (n< 13000) 合并在一起,为每个学生创建一个单独的列
  3. 像 courseDetails 这样的对象如何绑定到 xtragrid。

在 Gist 上演示 Linqpad

可以在 gist 上找到演示 linqpad 程序

班级课程详情

下面的类代表一所学校的一门课程。

public class CourseDetails{
    public int Id{ get; set;}
    public Course Course{ get; set;}
    public Teacher Teacher{get; set;}
    public Room Room{get; set;}
    public List<Student> StudentList{get; set;}
}

清单List<CourseDetails>

a 中的每个对象都List<CourseDetails>包含一个学生列表。有时学生列表中只有少数学生(2 到 5 名),有时每个学生列表有 15 到 40 名学生。CourseDetails 之间的学生可以重叠,但也可以不相交(不相交/不重叠)

第一个var cd1 = new CourseDetails()包含 3 名学生List<Student>

var cd1 = new CourseDetails(){
    Id =1 
    ,Course = new Course(){CourseId = 435, CourseName="C# Ninja"}
    ,Teacher = new Teacher(){TeacherId=48, TeacherName="J Skee"}
    ,Room = new Room(){RoomId=32, RoomName="base floor R001"}
    ,StudentList = new List<Student>(){
        new Student(){Id = 101, StudentName="Amy"}
        ,new Student(){Id = 104, StudentName="Koothrap"}
        ,new Student(){Id = 105, StudentName="Cooper"}
    }
};

第二个var cd2 = new CourseDetails()包含 2 名学生List<Student>

var cd2 = new CourseDetails(){
    Id =1 
    ,Course = new Course(){CourseId = 201, CourseName="SQL Basics"}
    ,Teacher = new Teacher(){TeacherId=30, TeacherName="M Gra"}
    ,Room = new Room(){RoomId=80, RoomName="2th floor R100"}
    ,StudentList = new List<Student>(){
        new Student(){Id = 101, StudentName="Amy"}
        ,new Student(){Id = 102, StudentName="Penny"}
    }
};

为了简化屏幕截图,请使用 aTuple<string, string,....>但对于网格,我希望每列都有基础属性的数据类型(int、string、date、...)。以开头的第一行将Id, Course, Teacher, Amy, ...是网格的标题。

4

2 回答 2

3

好的,我不知道这是否可行,但是当我们将网格绑定到对象列表时,我们会做类似的事情,然后根据用户选择的月份,我们在运行时将月份中的日期添加为列 - 并且根据应用程序中的其他数据填充。然而,在我看来,如果您不需要编辑数据,这可以通过在数据库中创建一个视图,然后简单地将视图数据作为 DataTable 返回并直接绑定到它来轻松实现。方式,更容易。不幸的是,我们不得不编辑数据,这不是一件容易的事!

无论如何,希望你能通过它自己的方式。

  1. 你有一个 CourseDetails 列表,每个都有一个学生列表。
  2. 在设计器中创建网格,并创建将绑定到 CourseDetails 属性(ID、Course、Teacher、Room)的静态列
  3. 在运行时,将网格的数据源设置为课程详细信息列表。执行此操作时/之前,您必须从 CourseDetails 列表中提取不同的学生姓名,您可以使用 LINQ 来执行此操作(类似于 [未测试])-

var names = CourseDetails.SelectMany(c => c.StudentList).Select(s => s.Name).Distinct();

将这些列作为未绑定列添加到您的网格中,例如:

    //Make sure you clear existing unboundcolumns
    foreach(string name in names)
    {
       int idx = gridView.Columns.Add(new GridColumn());
       gridView.Columns[idx].Visible = true;
       gridView.Columns[idx].Tag = name;
       gridView.Columns[idx].Caption = name;
       gridView.Columns[idx].UnboundType = UnboundColumnType.Integer;
    }

现在处理CustomUnboundColumnDatagridview 上的事件。您将需要执行与此类似的操作(不确定要如何匹配 - ID/名称):

    CourseDetail course = e.Row as CourseDetails;
    if (e.IsGetData)
    {
        e.Value = course.StudentList.Where(s => s.Name == e.Column.Tag.ToString()).Count();  
    }

如果您需要匹配 ID(将 ID 放在 Column.Tag 属性中):

e.Value = course.StudentList.SingleOrDefault(s => s.ID == (int)e.Column.Tag).Grade;

或您需要显示的任何内容。显然需要做空检查等。

希望那些对你有帮助。仍然认为你叫错了树,但无论如何......

于 2013-08-14T01:22:50.833 回答
1

实际上,无论如何您都必须在 C# 中进行旋转,因为当您想要将数据绑定(或无论如何提供)您的 UI 时 - 您的视图对象是Course(我不知道它是否也是您的域对象;或者您是否使用了一些ORM 与否)- 从数据库中提取的数据透视数据不会(直接)帮助(正在编排您的 UI),您应该执行一些 LINQ group by 操作以提取Course.

于 2013-05-27T19:33:03.427 回答