RadChart data binding provides a simple and consistent way for applications to present and interact with data. In many cases the data that you work with is a collection of objects and you need the UI to update automatically whenever the datasource gets updated. WPF and Silverlight provide a built-in implementation of a data collection that implements the INotifyCollectionChanged interface and achieves the desired effect.
However, when you try to blend the ObservableCollection<T> implementation with some LINQ queries, the situation gets a bit more complicated and most probably the out-of-the-box result will not match your expectations.
Let us take the following code:
SeriesMapping mapping = new SeriesMapping();
mapping.ItemMappings.Add(new ItemMapping("UnitsInStock", DataPointMember.YValue));
mapping.ItemMappings.Add(new ItemMapping("Category", DataPointMember.Label));
RadChart1.SeriesMappings.Add(mapping);
ObservableCollection<UserData> dataList = new ObservableCollection<UserData>();
RadChart1.ItemsSource = from data in dataList
where data.UnitsInStock > 100
select data;
dataList.Add(new UserData { UnitsInStock = 70, Category = "Beverages"});
dataList.Add(new UserData { UnitsInStock = 170, Category = "Dairy Products" });
dataList.Add(new UserData { UnitsInStock = 340, Category = "Grains Cereals" });
dataList.Add(new UserData { UnitsInStock = 240, Category = "Produce" });
dataList.Add(new UserData { UnitsInStock = 40, Category = "Seafood" });
One would expect that in the end the chart will display the three items that satisfy the where clause, however, with the code above the control will remain empty.
It turns out that the objects returned by LINQ queries do not provide CollectionChanged events thus it is difficult to display changes to data while simultaneously using LINQ. That's where BindableLinq comes to the rescue. With a minor code change, you can enable change notifications for LINQ queries seamlessly for the chart control like this (note the AsBindable( ) call added in the from clause):
SeriesMapping mapping = new SeriesMapping();
mapping.ItemMappings.Add(new ItemMapping("UnitsInStock", DataPointMember.YValue));
mapping.ItemMappings.Add(new ItemMapping("Category", DataPointMember.Label));
RadChart1.SeriesMappings.Add(mapping);
ObservableCollection<UserData> dataList = new ObservableCollection<UserData>();
RadChart1.ItemsSource = from data in dataList.AsBindable()
where data.UnitsInStock > 100
select data;
dataList.Add(new UserData { UnitsInStock = 70, Category = "Beverages"});
dataList.Add(new UserData { UnitsInStock = 170, Category = "Dairy Products" });
dataList.Add(new UserData { UnitsInStock = 340, Category = "Grains Cereals" });
dataList.Add(new UserData { UnitsInStock = 240, Category = "Produce" });
dataList.Add(new UserData { UnitsInStock = 40, Category = "Seafood" });
Here is the result:
You can find attached a sample Silverlight application to get you started as well.