0

I'm having some problems to export a DataGridView to Excel.

So, after user choose some filters, the data is passed to another form and the user has the option to export to excel, but there's an error saying "Cannot cast object List to DataTable.

Let me show you the code...

Query to List --> Working fine

public class Users
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }

public IEnumerable<Users> LoadUsers()
    {
        var ctx = new Entities();
        var query = (from p in ctx.tblUser.AsQueryable()
                     join c in ctx.tblNames on p.NameID equals c.NameID
                     join e in ctx.tblAddresses on p.AddressID equals e.AddressID
                     select new Users
                     {
                         ID = p.ProjetoID,
                         Name = c.Name,
                         Address = e.Address
                     });
        return query.ToList();
    }

Button Click Event

private void BtnSearch_Click(object sender, EventArgs e)
    {
        if(LoadUsers() == null)
        {
            MessageBox.Show("No results!", "No results", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        else
        {
            UsersSearch_List searchlist = new UsersSearch_List();
            searchlist.users_datagrid.DataSource = LoadUsers();
            searchlist.MdiParent = MdiParent;
            searchlist.Show();
        }
    }

On the other Form, the data loads OK in users_datagrid DataGridView. But, when User clicks on Export Button:

private void exportToolStripMenuItem_Click(object sender, EventArgs ev)
    {
        DataTable dt = new DataTable();
        dt = (DataTable)users_datagrid.DataSource; //--> The error occurs here... Cannot cast object List to DataTable.

        //This is a Helper I have to convert List to DataTable, but it don't works eather!!!
        //DataTable dt = ConvertListToDataTable.ToDataTable(projetos_datagrid);

        if (saveFileDialog.ShowDialog() != DialogResult.OK)
        {
            return;
        }
        string TargetFileName = saveFileDialog.FileName;
        try
        {
            CreateExcelFile.CreateExcelDocument(dt, TargetFileName);
        }
        catch (Exception ex)
        {
            MessageBox.Show("Error: " + ex.Message);
            return;
        }
        Process process = new Process();
        process.StartInfo = new ProcessStartInfo(TargetFileName);
        process.Start();
    }

Can someone help me???

  • when do you set users_datagrid datasource? – NicoRiff Jun 27 '18 at 13:24
  • If `users_datagrid.DataSource` isn't a `DataTable`, you won't be able to cast it that way, no. It's not clear what your `ConvertListToDataTable` does, or how that's failing for you. At the moment I'm afraid it's quite hard to help you with only the information we've got. – Jon Skeet Jun 27 '18 at 13:25
  • Also note that your question title is "C# DataTable type arguments cannot be inferred" - it's not clear where that comes into the question. – Jon Skeet Jun 27 '18 at 13:26
  • Possible duplicate of [Convert generic List/Enumerable to DataTable?](https://stackoverflow.com/questions/564366/convert-generic-list-enumerable-to-datatable) – Murat Gündeş Jun 27 '18 at 13:28
  • I've changed my title accordingly to my error. I'm not setting users_datagrid datasource because the users_datagrid is populated by the Parent Form. My problem is only to export this to excel, since I need a DataTable. When I cast users_datagrid to DataTable (DataTable)users_datagrid.DataSource, I have error "Cannot cast List to DataTable". – Carlos Ferreira Jun 27 '18 at 13:32
  • OT `DataTable dt = new DataTable(); dt = ...` You are creating a new DataTable and then *ignore* it by assigning a new value to `dt` and leaving the old value for the GC to collect. An assignment doesn't "fill" the previous value, it *replaces* it. – Hans Kesting Jun 27 '18 at 13:44

1 Answers1

0

You should create a new DataTable and populate it using the list:

    public static DataTable ToDataTable<T>(this IList<T> data)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        {
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        }
        return table;
    }
DavisZ
  • 141
  • 9