Databinding to nested collections

4 posts, 0 answers
  1. Farhan
    Farhan avatar
    23 posts
    Member since:
    Sep 2010

    Posted 02 Aug 2011 Link to this post

    Hi,

    I want to use xaml for binding nested collections to the the RadChart. However I don't want to hard code each series mapping manually like the examples show when they make use of multiple datasources or collection index.

    As I can draw N number of series on chart at a given time hence hard-coding the series is impractical. Therefore I wanted to know how to handle this case in the most elegant way, by purely using Xaml and databinding the following data structure.

    public class Data : INotifyPropertyChanged
        {
            private double m_Value;       
            private int m_Period;
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            public double Value
            {
                get
                {
                    return m_Value;
                }
                set
                {
                    if (m_Value == value)
                        return;
     
                    m_Value = value;
                    this.OnPropertyChanged("Value");
                }
            }
           
            public int Period
            {
                get
                {
                    return m_Period;
                }
                set
                {
                    if (m_Period == value)
                        return;
     
                    m_Period = value;
                    this.OnPropertyChanged("Period");
                }
            }
     
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
     
        public class DataPointSeries : INotifyPropertyChanged
        {
            private ObservableCollection<Data> m_DataList;
            public ObservableCollection<Data> DataList
            {
                get
                {
                    return m_DataList;
                }
                set
                {
                    m_DataList = value;
                    OnPropertyChanged("DataList");
                }
            }              
     
            public event PropertyChangedEventHandler PropertyChanged;
     
            protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
     
    public class ChartsViewModel
        {
     
            private ObservableCollection<DataPointSeries> m_DataPointSeriesCollection;
            public ObservableCollection<DataPointSeries> DataPointSeriesCollection
            {
                get
                {
                    return m_DataPointSeriesCollection;
                }
                set
                {
                    m_DataPointSeriesCollection = value;
                }
            }
     
            public void PopulateDataSeriesCollection()
            {
                DataPointSeriesCollection = new ObservableCollection<DataPointSeries>
                {               
     
                    new DataPointSeries
                    {
                         DataList = GetDataPoint(0)
                    },
                    new DataPointSeries
                    {
                        DataList = GetDataPoint(12.75)
                    },
                    new DataPointSeries
                    {
                        DataList = GetDataPoint(27.625)
                    },
                    new DataPointSeries
                    {
                        DataList = GetDataPoint(37.675)
                    },
                    new DataPointSeries
                    {
                        DataList = GetDataPoint(43.475)
                    }
                };
            }
     
            public ObservableCollection<Data> GetDataPoint(double factor)
            {
                var dataList = new ObservableCollection<Data>()
                        {
                            new Data
                            {
                                Period = 2002,
                                Value = 15 + factor
                            },
                            new Data
                            {
                                Period = 2003,
                                Value = 25 + factor
                            },
                            new Data
                            {
                                Period = 2004,
                                Value = 35 + factor
                            },
                            new Data
                            {
                                Period = 2005,
                                Value = 55 + factor
                            },
                            new Data
                            {
                                Period = 2006,
                                Value = 65 + factor
                            },
                            new Data
                            {
                                Period = 2007,
                                Value = 75 + factor
                            }
                        };
                        return dataList;               
            }
        }


    Thanks,
    Farhan
  2. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 05 Aug 2011 Link to this post

    Hello Farhan,

    First I see that the data in your view model is a collection of DataPointSeries. In this scenario you can use our CollectionIndex functionality to access the data from the nested collection.
    RadChart Series Mapping CollectionIndex functionality supports 2 level nested collections and in your case you access your last level through a property. One way of workarounding this can be to implement IEnumerable<T> on your DataPointSeries class like this:

    public IEnumerator<Data> GetEnumerator()
    {
        return this.DataList.GetEnumerator();
    }
     
    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }

    RadChart SeriesMappings collection can be data bound to your view model easily and from there you can control the number of series that you want to be displayed simply by controlling the number of series mappings.

    I have attached a sample project that uses your code and creates series mappings in your view model. Please give it a try and tell me how it is.

    Best wishes,
    Yavor Ivanov
    the Telerik team

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

  3. UI for WPF is Visual Studio 2017 Ready
  4. Farhan
    Farhan avatar
    23 posts
    Member since:
    Sep 2010

    Posted 08 Aug 2011 Link to this post

    Thanks for the sample. It is fairly detailed to cater to my needs.

    However there is a ArgumentNullException that happens when I am viewing the MainWindow.xaml file. It says:

    "ArgumentNullException" was thrown on the "RadChart" Value cannot be null.
    Parameter name: source.

    Details:

    Value cannot be null.Parameter name: source

    at System.Linq.Enumerable.Any[TSource](IEnumerable`1 source, Func`2 predicate) at Telerik.Windows.Controls.RadChart.InternalRebind() at Telerik.Windows.Controls.RadChart.OnApplyTemplate() at System.Windows.FrameworkElement.ApplyTemplate() at Microsoft.Expression.Platform.WPF.WpfViewNodeManager.EnsureElementInDictionary(Object root, ViewNode knownAncestor)

    Can you please look into the issue?

    Thanks,
    Farhan

  5. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 11 Aug 2011 Link to this post

    Hello Farhan,

    Unfortunately we couldn't reproduce the exception you mentioned. I have added Q2 binaries to the solution. Just build it and It should be runnable without any exceptions.

    Best wishes,
    Yavor Ivanov
    the Telerik team

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

Back to Top