Retrieve the selected line (class) from DataGridView as an object class (Unable to launch object)

I have the following class named Students:

namespace ClassLibrary
{
    using System;
    using System.Collections.Generic;

    public partial class Students
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Students()
        {
            this.Scenarios = new HashSet<Scenario>();
        }

        public int StudentsID { get; set; }
        public System.DateTime CreatedOn { get; set; }
        public string CreatedBy { get; set; }
        public System.DateTime UpdatedOn { get; set; }
        public string UpdatedBy { get; set; }
        public string StudentsCode { get; set; }
        public string StudentsName { get; set; }
        public bool isActive { get; set; }
        public string Comments { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Scenario> Scenarios { get; set; }
    }
}

And I load data as a list in a DataGridView. This works fine:

public partial class myCLASS : Form
{
    ...

    private void myCLASS_Load(object sender, EventArgs e)
    {

        myDataGridView.DataSource = (from x in _context.Students
        orderby x.MFlowOrdering
        select new { x.StudentsID,x.StudentsCode,x.StudentsName}).ToList();
    }

    private void myDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
      Students SelectedRow =(Students)(myDataGridView.CurrentRow.DataBoundItem);
      MessageBox.Show(SelectedRow.StudentsID);
    }
    ...
}

Now, I want each time I click on a row in the DataGridView (only full row selection is enabled), I want to retrieve the object (Selected Class Students) behind the selected row:

private void myDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
  Students SelectedRow =(Students)(myDataGridView.CurrentRow.DataBoundItem);
  MessageBox.Show(SelectedRow.StudentsID);
}

And I receive the following error:

Additional information: Unable to cast object of type '<>f__AnonymousType0`5[System.Int32,System.Int32,System.String,System.String,System.Boolean]' to type 'ClassLibrary.Students'.

I Google it and it seems that I use the correct syntax.

Could you please advice?


You're using the anonymous type while binding the grid. Try selecting the Students type in the query as follows:

private void myCLASS_Load(object sender, EventArgs e)
{
    myDataGridView.DataSource = (from x in _context.Students
    orderby x.MFlowOrdering
    select new Students {
                StudentsId = x.StudentsID,
                StudentsCode = x.StudentsCode,
                StudentsName = x.StudentsName
    }).ToList();
}

UPDATE

In case an anonymous type is preferred for binding, you could use dynamic keyword instead of casting the data bound item to Students entity as follows:

private void myCLASS_Load(object sender, EventArgs e)
{
    myDataGridView.DataSource = (from x in _context.Students
    orderby x.MFlowOrdering
    select new {
                StudentsId = x.StudentsID,
                StudentsCode = x.StudentsCode,
                StudentsName = x.StudentsName
    }).ToList();
}

private void myDataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
  dynamic SelectedRow = myDataGridView.CurrentRow.DataBoundItem;
  MessageBox.Show(SelectedRow.StudentsID);
}