GridView fails to bind to custom collection

2 posts, 0 answers
  1. Enal
    Enal avatar
    39 posts
    Member since:
    Oct 2011

    Posted 28 May 2012 Link to this post

    Hi.

    We want to populate our grid with data that contains custom collections implementing 
    INotifyCollectionChangedIList<object>

    It tests fine for all conditions and for example this works just as expected

                var cA = new ObservableCollection<object> {1, 2, 3, "A""B""C"null};
                var cB = new ObservableCollection<object> { 10, 20, 30, "AA""BB""CC"null };
                var collection = new ConjoinedCollection(cA, cB);
                var combo = new ComboBox {ItemsSource = collection};
    

    However, when I stick our data ObservableCollection<ConjoinedCollection> into GridView I get the following exception for every visible index (column):

    System.Windows.Data Error: Failed to connect to index '2' in object 'Commons.Model.Collections.ConjoinedCollection`1[System.Object]' (type 'Commons.Model.Collections.ConjoinedCollection`1[System.Object]'). BindingExpression: Path='[2]' DataItem='Commons.Model.Collections.ConjoinedCollection`1[System.Object]' (HashCode=16028238); target element is 'Telerik.Windows.Controls.GridViewBoundColumnBase+ValueSetter' (Name=''); target property is 'Value' (type 'System.Object').
    

    Lastly, If I process our ObservableCollection<OurCustomCollection> as follows (i.e. convert it into an ObservableCollection<ObservableCollection<object>>, it works.

                    var viewData = new ObservableCollection<ObservableCollection<object>> ();
                    foreach (var row in _viewModel.Data) // iterate through OC<CustomCollection>
                        viewData.Add(new ObservableCollection<object>(row));
    
                    tkGrid.ItemsSource = viewData;
    

    Any idea what is going on here and how to fix this without re-wrapping the data?

    Thanks!
  2. Enal
    Enal avatar
    39 posts
    Member since:
    Oct 2011

    Posted 29 May 2012 Link to this post

    Follow up...

    So we are binding to an ObservableCollection<ConjoinedCollection<object>> where ConjoinedCollection is a custom collection implementing INotifyCollectionChanged and IList. However, it appears GridView is treating the inner collection as a bean, tries to bind to its properties and ignores its IList API - and thus fails binding to [<index>].

    A workaround is to bind to "." instead, i.e. to the entire row, cast it back to its actual Type and execute the IList API with a converter.

            public object Convert(object value_, Type targetType_, object parameter_, CultureInfo culture_){
                var row = value_ as ConjoinedCollection<object>;
                var value = row != null ? row[_index] : null; // TODO: Consider non-nullable types
                return value;
            }

    This sort of works but we have concerns that other Telerik components may fail.

    Could you please shed some light on how this works internally and why our IList is being ignored - or ideally show a better solution without this workaround (note - using beans instead of a collection, which seems to be the general assumption in the documentation is not an option for us; Also, this works without this workaround with ObservableCollection<ObservableCollection<object>> instead of our custom collection).

    Thanks!
Back to Top