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

Databinding to nested collections

3 Answers 106 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Farhan
Top achievements
Rank 1
Farhan asked on 02 Aug 2011, 08:41 PM
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

3 Answers, 1 is accepted

Sort by
0
Yavor
Telerik team
answered on 05 Aug 2011, 09:40 AM
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 >>

0
Farhan
Top achievements
Rank 1
answered on 08 Aug 2011, 09:32 PM
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

0
Yavor
Telerik team
answered on 11 Aug 2011, 01:18 PM
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 >>

Tags
Chart
Asked by
Farhan
Top achievements
Rank 1
Answers by
Yavor
Telerik team
Farhan
Top achievements
Rank 1
Share this question
or