J-P
J-P

Reputation: 403

how to set Row Filtered DataGridView to DataTable in C#

I have DataGridview that I filtered some of it's row, I need to save the new datasource to a new DataTable, for some reason my current code don't work, here how I'm trying to convert it.

(LogGridView.DataSource as DataTable).DefaultView.RowFilter = string.Format("Type IN({0}) AND Date >= {1} AND Date <= {2} AND Content {3} '%{4}%'", typeFilter, startDate, endDate, likeQuery,keywordFilter.Text);
        this.LogGridView.Sort(this.LogGridView.Columns[0], ListSortDirection.Ascending);
FilteredTable =  LogGridView.DataSource as DataTable;

 public DataTable FilteredTable
    {
        get;
        set;
    }

any Idea why it is not working

Thanks

Upvotes: 3

Views: 1433

Answers (1)

OhBeWise
OhBeWise

Reputation: 5454

What you have seen here is that after applying a filter and a sort, the sourced DataTable is unchanged though the DataGridView displays as expected. This is by design. So calling:

FilteredTable =  LogGridView.DataSource as DataTable;

Just sets FilteredTable to the same as the original table.

Instead, we'll create a method to:

  1. Create a new table with the same columns.
  2. Select the rows from the original table using the same filter string and equivalent sort string as the DataGridView sort.
  3. For each selected row, clone the items and add them as a new row into the new table.
  4. Return the new table.

As seen here:

private DataTable CloneAlteredDataTableSource(DataGridView dgv)
{
    DataTable dt = dgv.DataSource as DataTable;

    if (dt == null)
    {
        return null;
    }

    DataTable clone = new DataTable();

    foreach (DataColumn col in dt.Columns)
    {
        clone.Columns.Add(col.ColumnName, col.DataType);
    }

    string order = string.Empty;

    switch (dgv.SortOrder)
    {
        case SortOrder.Ascending: order = "ASC"; break;
        case SortOrder.Descending: order = "DESC"; break;
    }

    string sort = dgv.SortedColumn == null ? string.Empty : string.Format("{0} {1}", dgv.SortedColumn.Name, order);

    DataRow[] rows = dt.Select(dt.DefaultView.RowFilter, sort);

    foreach (DataRow row in rows)
    {
        object[] items = (object[])row.ItemArray.Clone();
        clone.Rows.Add(items);
    }

    return clone;
}

And usage:

(this.LogGridView.DataSource as DataTable).DefaultView.RowFilter = string.Format("Type IN({0}) AND Date >= {1} AND Date <= {2} AND Content {3} '%{4}%'", typeFilter, startDate, endDate, likeQuery,keywordFilter.Text);
this.LogGridView.Sort(this.LogGridView.Columns[0], ListSortDirection.Ascending);
this.FilteredTable =  this.CloneAlteredDataTableSource(this.LogGridView);

Upvotes: 2

Related Questions