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

ItemsSource to QueryableCollectionView bound to RadGridView during grouping

11 Answers 309 Views
TileView
This is a migrated thread and some comments may be shown as answers.
Patrick
Top achievements
Rank 1
Patrick asked on 14 Dec 2016, 05:33 PM

Hello,

We have a TileView and GridView on the UI side by side bound to the same collection inside a ViewModel using a QueryableCollectionView, which is sourced by an ObservableCollection<MyGridData>. When the GridView is filtered, sorted, items are added/removed, etc the TileView works and updates perfectly. Our only issue is when the GridView is grouped, the underlying class of the inside the QueryableCollectionView changes from MyGridData to a new Grouping Class, which the TileView templates do not know how to render. This causes the count of TileView items to match the number of groupings, and the TileView icons themselves to be blank.

How do you recommend binding these two controls to allow the GridView to group and still hand back MyGridData in the grouped order?

Thank you,

Patrick

11 Answers, 1 is accepted

Sort by
0
Patrick
Top achievements
Rank 1
answered on 16 Dec 2016, 06:44 PM
Only 1 view. Anyone? Bueller?
0
Petar Mladenov
Telerik team
answered on 19 Dec 2016, 09:21 AM
Hi Patrick,

Grouping in RadTileView is not supported out of the box. You can vote for the following feature request.

TileView: Add grouping support.

What we can suggest you is implementing custom grouping. For example you need normal ContentTemplate for RadTileView in non-grouped state and custom ContentTemplate (containing for example ListBox) for grouped RadTileView. Switching these templates and ItemsSource of the RadTileView could be done in the GridView grouping events.


Regards,
Petar Mladenov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Patrick
Top achievements
Rank 1
answered on 19 Dec 2016, 03:49 PM

Hello Petar,

We would prefer the TileView look exactly the same and essentially ignore the grouping but maintain the item order. This would be more of a change to the source collection. We have this in other parts of our UI where the GridView and the TileView have two different source collections that represent the same list of items. Keeping the two collections in sync without issue can be a challenge. This is where the QueryableCollectionView bound to the GridView was *almost* exactly what we needed, with the exception of grouping. We were inquiring if you had another method to essentially flat list the items for the TileView when grouping.

Right now I am looking into creating a derived class of QueryableCollectionView which has a property called 'GrouplessSource', but again this is maintaining a separate list of items and is far from ideal.

Do you have any other suggestions?

Thank you Petar.

0
Petar Mladenov
Telerik team
answered on 22 Dec 2016, 09:46 AM
Hello Patrick,

We would suggest using a converter for the ItemsSource binding of the RadTileView. If groups are passed in the converter and they provide child collections of (flat) item, then create the flat collection you need in the converter.  However, this is only shoot in the dark. We tried to replicate your scenario - GridView and TileView both bound to QueryableCollectionView. Please check out our test project and notice that when you group by Name column, the TileView does not change. Can you edit the project to replicate your scenario ?

Regards,
Petar Mladenov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Patrick
Top achievements
Rank 1
answered on 22 Dec 2016, 01:44 PM

Hello again Petar,

I could not reproduce the issue in your attached app. After tweaking a few things in both our SL app, and your WPF app I decided to make a SL app with exactly the same code as your test app and it reproduced our issue immediately. I cleared out DisplayMemberPath to call ToString() on the underlying class. It looks like they are different in SL vs WPF. The WPF behavior is what we are looking for, although the SL behavior is more what I would expect when the grouping is added to a QueryableCollectionView. Which one is "correct"?

If you'd like I'd be happy to zip up both projects to send them, but I can't attach files in this forum.

Thanks for your time on this.

 

0
Petar Mladenov
Telerik team
answered on 27 Dec 2016, 08:10 AM
Hello Patrick,

There are some implementation differences in Silverlight / WPF regarding grouping with QueryableCollectionView. However, your main goal is to ignore the grouping in RadTileView, right. We want to suggest the following - bind the ItemsSource of the RadTileVeiw to the SourceCollection property of the QCV:

QueryableCollectionView view = new QueryableCollectionView(Club.GetClubs());
         this.grid.ItemsSource = view;
         this.DataContext = view;

<telerik:RadTileView DisplayMemberPath="Name" x:Name="tileView" Grid.Row="2"
                           ItemsSource="{Binding SourceCollection}">

This way the TileView will remain with tielviewitems number equal to the items in the source collection of the QCV and will ignore the grouping. Please find this realized in the attached SL project. Additionally, please excuse us for misleading you with WPF project, instead of SIlverlight's int he previous reply.

Regards,
Petar Mladenov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Patrick
Top achievements
Rank 1
answered on 28 Dec 2016, 04:07 PM

Hello Petar,

I'm afraid that won't work for us either, the SourceCollection does not update with sorting and filtering as binding directly to the QueryableCollectionView does. This is the expected behavior in the rest of our UI, the TileView is a representation of the GridView items. As stated previously it's almost perfect, with great performance without having to maintain 2 sources, except we want to flat list when grouping, which it seems WPF does and SL does not.

I tried a converter on the TileView itemsource as previously suggested, but this is only called once on instantiation. This does not help when a grouping is added, the converter is not called again. If it was, we could easily loop though recursively find all the groups within groups and hand back the flat listed items ourselves.

Any other suggestions?

Thank you,

Patrick

0
Petar Mladenov
Telerik team
answered on 30 Dec 2016, 10:07 AM
Hello Patrick,

We understand binding is not updated when grouping is performed. Is using Grouping events still an option, use the event and manually re-set the ItemsSource of the RadTileView on group / ungroup ?

RadGridView Grouping Events

Regards,
Petar Mladenov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Patrick
Top achievements
Rank 1
answered on 30 Dec 2016, 06:16 PM

Hello Petar,

I was able to get what appears to be the desired behavior with a mixture of things. The RadTileView has a converter on the ItemsSource, the grid has a 'Grouped' event handler (only for grouping removes), and the QueryableCollectionView has an event handler on changes (this keeps up with changes to grid sorts/filters on the grid while grouping)

public class QCVGroupFlatListConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var source = value as QueryableCollectionView;
        if (source != null && source.IsGrouped)
        {
            var ungrouped = new List<object>();
            for (int i = 0; i < source.Count; i++)
            {
                var d = source[i] as object;
                if (d != null)
                {
                    ungrouped.Add(d);
                }
            }
 
            return ungrouped;
        }
 
        return value;
    }
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

 

01.public partial class MainPage : UserControl, INotifyPropertyChanged
02.{
03.    #region INotifyPropertyChanged Members
04. 
05.    protected void OnPropertyChanged(string property)
06.    {
07.        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
08.    }
09. 
10.    public event PropertyChangedEventHandler PropertyChanged;
11. 
12.    #endregion INotifyPropertyChanged Members
13. 
14.    private QueryableCollectionView _MyList;
15. 
16.    public QueryableCollectionView MyList
17.    {
18.        get { return _MyList; }
19.        set
20.        {
21.            if (_MyList == value)
22.                return;
23. 
24.            _MyList = value;
25.            OnPropertyChanged(nameof(MyList));
26.        }
27.    }
28. 
29.    public MainPage()
30.    {
31.        MyList = new QueryableCollectionView(Club.GetClubs());
32.        MyList.CollectionChanged += MyList_CollectionChanged;
33.        DataContext = this;
34. 
35.        InitializeComponent();
36.    }
37. 
38.    private void MyList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
39.    {
40.        if (((QueryableCollectionView)sender).IsGrouped)
41.            OnPropertyChanged(nameof(MyList));
42.    }
43. 
44.    private void RadGridView_Grouped(object sender, Telerik.Windows.Controls.GridViewGroupedEventArgs e)
45.    {
46.        if (e.Action == Telerik.Windows.Controls.GroupingEventAction.Remove)
47.            OnPropertyChanged(nameof(MyList));
48.    }
49.}

 

I believe this is causing the grid to reevaluate it's own ItemsSource on group changes since it is also bound to 'MyList', but I didn't notice any performance issues, even with 1000+ items. Perhaps the grid is ignoring the update since no real change is happening?

 

Worth noting is how looping through a QueryableCollectionView behaves in SL:

foreach() and for() on QueryableCollectionView while grouping return two completely different things
for() accessed with an index, as in source[i], returns the underlying object whereas
foreach() returns AggregateFunctionsGroup, which could be nested with more groups
ex: [Group: Key=Arsenal; ItemCount=2; HasSubgroups=False; ParentGroup=null]

Thank you,

Patrick

0
Accepted
Petar Mladenov
Telerik team
answered on 04 Jan 2017, 03:13 PM
Hi Patrick,

Here are our answers:

Perhaps the grid is ignoring the update since no real change is happening?

Yes the grid find there is no change of the ItemsSource object.

Worth noting is how looping through a QueryableCollectionView behaves in SL:

When you *for* you use the indexator element[i], and when you use *foreach* you use the enumerator returned by the GetEnumerator method so the mentioned difference is expected.

We also wanted to suggest another solution you can try - bind the ItemsSource of the RadTileView to the GridView's Items property:

<telerik:RadTileView DisplayMemberPath="Name" x:Name="tileView" Grid.Row="2" ItemsSource="{Binding Items, ElementName=grid}">




Regards,
Petar Mladenov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
0
Patrick
Top achievements
Rank 1
answered on 09 Jan 2017, 04:19 PM

This single line is what we needed.

ItemsSource="{Binding Items, ElementName=grid}"

Thank you.

Tags
TileView
Asked by
Patrick
Top achievements
Rank 1
Answers by
Patrick
Top achievements
Rank 1
Petar Mladenov
Telerik team
Share this question
or