davidegironi / advanceddatagridview

A .NET WinForms DataGridView with advanced capabilities
392 stars 123 forks source link

Allow DataTable/DataView as DataSource with automatic sorting and filtering #60

Closed kirsan31 closed 3 years ago

kirsan31 commented 3 years ago

Hi. I was trying to set DataTable or DataView directly as DataSource. And this lead to filtering and sorting are stop working automatically. What do you think about adding DataTable and DataView to supported DataSources (even default DataGridView are support them)? Something like this: TriggerFilterStringChanged:

if (this.DataSource is BindingSource datasource)
{
    datasource.Filter = filterEventArgs.FilterString;
}
else
{
    var dataView = (this.DataSource as System.Data.DataView) ?? (this.DataSource as System.Data.DataTable)?.DefaultView;
    if (dataView != null)
        dataView.RowFilter = filterEventArgs.FilterString;
}

TriggerSortStringChanged:

if (this.DataSource is BindingSource bindingSource)
{
    bindingSource.Sort = sortEventArgs.SortString;
}
else
{
    var dataView = (this.DataSource as System.Data.DataView) ?? (this.DataSource as System.Data.DataTable)?.DefaultView;
    if (dataView != null)
        dataView.Sort = sortEventArgs.SortString;
}

This will allow to skip using excess BindingSource or manual sorting. Thanks.

davidegironi commented 3 years ago

Hello, that's sounds good, but this project is used with BindingSource, changing this behaviour will cause some refactoring in project that use this library. You can do this by attaching an event to the FilterStringChanged and SortStringChanged. Don't forget to set e.Cancel to skip the Filer and Sorting internal mechanism. Take a look at advancedDataGridView_main_FilterStringChanged and advancedDataGridView_main_SortStringChanged in the sample project as example.

kirsan31 commented 3 years ago

Hello, that's sounds good, but this project is used with BindingSource, changing this behaviour will cause some refactoring in project that use this library. You can do this by attaching an event to the FilterStringChanged and SortStringChanged. Don't forget to set e.Cancel to skip the Filer and Sorting internal mechanism. Take a look at advancedDataGridView_main_FilterStringChanged and advancedDataGridView_main_SortStringChanged in the sample project as example.

I think you didn't get it. This is addition (not replace) and will not require refactoring because for now (as your said above) if you use other datasource beside BindingSource you need to use FilterStringChanged + SortStringChanged and set e.Cancel to true. So new code will never be called, becose it inside

if (filterEventArgs.Cancel == false)
{
}

It's just strange that of the two standard classes (DataView, BindingSource) that implement IBindingListView advanceddatagridview out of the box can work only with BindingSource. But it's your decision any way. Thank you once more.

davidegironi commented 3 years ago

Now I get this. You mean something like this? for TriggerFilterStringChanged:

//...
if (filterEventArgs.Cancel == false)
{
    if (this.DataSource is BindingSource bindingsource)
    {
        bindingsource.Filter = filterEventArgs.FilterString;
    }
    else if (this.DataSource is DataView dataview)
    {
        dataview.RowFilter = filterEventArgs.FilterString;
    }
    else if (this.DataSource is DataTable datatable)
    {
        if (datatable.DefaultView != null)
            datatable.DefaultView.RowFilter = filterEventArgs.FilterString;
    }
}
//...
kirsan31 commented 3 years ago

Exactly. All my code from 1 post must replace code in this condition:

if (filterEventArgs.Cancel == false)
{
}

Sorry for misleading.

davidegironi commented 3 years ago

Hello, I'm posting your code update in the next deploy, if you want a preview download it from here: https://github.com/davidegironi/advanceddatagridview/issues/68#issuecomment-868566190