This is a migrated thread and some comments may be shown as answers.

Filtering and grouping of ObservableCollection inside GridView

2 Answers 74 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Manuel
Top achievements
Rank 1
Manuel asked on 18 Nov 2011, 05:54 PM
Hey,
I have a GridView which is getting filled async via Binding in combination with MVVM-Pattern. Actually one of these objects is a ObservableCollection.
In order to display this collection inside the grid nicely I'm using the celltemplate, as shown in a short examplecode:
<telerik:GridViewDataColumn Header="Clients" DataMemberBinding="{Binding Clients}" Width="170" IsFilterable="True" IsGroupable="True">
    <telerik:GridViewDataColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="Content"/>
        </DataTemplate>
    </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>

However the problem or missing thing: I can't group or filter this column.
So imagine the gridview has2 rows:
row 1 having an object with 2 clients (A and B)
row 2 having an object with 2 clients (B and C)

I need now something like "filtering for client so that I only see objects that are in B" or group by client, getting a result like that:
A -> row-1-object
B-> row-1-object and row-2-object
C-> row-2-object

Instead of that I can't filter the column (because the icon is missing) and I can't event group that column. Grouping and filtering of all other columns works, because they contains just strings.

I hope it's clear and thanks for an answer in advance!

2 Answers, 1 is accepted

Sort by
0
Vlad
Telerik team
answered on 21 Nov 2011, 08:53 AM
Hello,

 I'm afraid that you cannot filter, group, sort, etc. a column bound to ObservableCollection since this is not IEquatable and/or IComparable.

Regards,
Vlad
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Manuel
Top achievements
Rank 1
answered on 21 Nov 2011, 11:03 AM
Thank you!
I solved it now a little bit complicated, but at least the filtering works - which was the main requirement.

I'll shortly post my solution, if it might help others:

The object which is in the ObservableCollection has two properties, as in this case UsersFullSummary and UsersSummary.
UsersFullSummary just returns the content of the collection as a semicolon-separated string, like "ElementA;ElementB;ElementC;" etc.
UsersSummary is responsible for the text I want to see, as in this case something like "5 Elements".

Now I define the GridViewColumn:

<telerik:GridViewDataColumn DataMemberBinding="{Binding UsersFullSummary}" IsGroupable="False" IsFilterable="True" ShowFieldFilters="False" Width="170">
                    <telerik:GridViewDataColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding UsersSummary}"/>
                        </DataTemplate>
                    </telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>

So the column itself shows the content of UsersSummary (e.g. "5 Elements") but the column contains all values, semicolon seperated ("ElementA;ElementB;"...).

Now you need to react on 2 events of the RadGridView: DistinctValuesLoading and Filtering.
In the eventhandler of DistinctValuesLoading you can check if the column is corresponding to your "custom" filter column and if so, return all elements distinct. Furthermore you need to "undo" filter-settings which you changed in the filtering-event, look at the other codeexample to understand it fully. For instance:

public void GridViewDistinctValuesLoading(object sender, GridViewDistinctValuesLoadingEventArgs e)
{
    String columnPath = e.Column.DataMemberBinding.Path.Path;
    if (columnPath == "UsersFullSummary")
    {
                ObservableCollection<String> usernames = new ObservableCollection<String>();
                ...
                e.ItemsSource = usernames;

                RadGridView gridView = (sender as RadGridView);
                foreach(ColumnFilterDescriptor columnFilter in gridView.FilterDescriptors)
                {
                    foreach (FilterDescriptor filter in columnFilter.DistinctFilter.FilterDescriptors)
                    {
                        if (filter.Member == "UsersFullSummary")
                        {
                            String filVal = filter.Value.ToString();
                            if (filVal.EndsWith(";"))
                            {
                                filter.Value = filVal.Substring(0, filVal.Length - 1);
                            }
                            filter.Operator = FilterOperator.Contains;
                        }
                    }
                }


    }
}

And in the eventhandler of filtering you just needs to change the FilterOperator and the Value (adding the ";" at the end of the value)
public void GridViewFiltering(object sender, GridViewFilteringEventArgs e)
{
    foreach (IFilterDescriptor ifilter in e.Added)
    {
        FilterDescriptor filter = ifilter as FilterDescriptor;
        if (filter != null && filter.Member == "UsersFullSummary")
        {
            filter.Operator = FilterOperator.Contains;
            filter.Value = filter.Value+";";
        }
    }
}

So after you examine the filtering-eventhandler, a short explanation to the second part of the DistinctValues-Eventhandler.
If it's missing you got the problem, that after making selections, closing the filterwindow and reopen it that no filters are preselected (because the values doesn't match - they have the ";" at the end). Therefore we loop through each setted filter and remove that ";" if It's applied. Now the GUI reflects this filters and after that the filtering-event get's called and the ";" are added again.

Some explanation to the filtering itself: As soon as you run the application and you select the filter icon the distinct-values from the corresponding eventhandler get loaded. If you now select one, telerik checks the UsersFullySummary text if it contains the element (for instance it searches in the UsersFullSummary "ElementA;ElementB;ElementC;" for the string text "ElementA;").

Of course a really big solution which isn't such easy as a normal filter, but it works!
If you know a possibility how to improve this, let me know!

For custom grouping I have no idea how to do this...
Tags
GridView
Asked by
Manuel
Top achievements
Rank 1
Answers by
Vlad
Telerik team
Manuel
Top achievements
Rank 1
Share this question
or