Hi Petar, thanks for your reply, and for passing my issue on to the developers. When you say "unless you toggle two different providers in your app", you can't do that and have both sets show on the graph at the same time, can you?
I've come up with minimal example of my issues for your reference:
MainWindow.xaml:
<
Window
x:Class
=
"TwoDynamic.MainWindow"
Title
=
"MainWindow"
Height
=
"350"
Width
=
"525"
>
<
Window.Resources
>
<
ResourceDictionary
>
<
DataTemplate
x:Key
=
"PointDataTemplate"
>
<
Ellipse
Width
=
"4"
Height
=
"4"
Fill
=
"Red"
/>
</
DataTemplate
>
</
ResourceDictionary
>
</
Window.Resources
>
<
Grid
>
<
telerik:RadCartesianChart
>
<
telerik:RadCartesianChart.Resources
>
<
Style
TargetType
=
"telerik:LineSeries"
>
<
Setter
Property
=
"StrokeThickness"
Value
=
"2"
/>
<
Setter
Property
=
"Stroke"
Value
=
"Blue"
/>
</
Style
>
<
Style
TargetType
=
"telerik:BarSeries"
>
<
Setter
Property
=
"PointTemplate"
Value
=
"{StaticResource PointDataTemplate}"
/>
<
Setter
Property
=
"CombineMode"
Value
=
"None"
/>
</
Style
>
</
telerik:RadCartesianChart.Resources
>
<
telerik:RadCartesianChart.Grid
>
<
telerik:CartesianChartGrid
MajorLinesVisibility
=
"XY"
/>
</
telerik:RadCartesianChart.Grid
>
<
telerik:RadCartesianChart.HorizontalAxis
>
<
telerik:DateTimeContinuousAxis
LabelFitMode
=
"Rotate"
LabelFormat
=
"MMM-dd"
/>
</
telerik:RadCartesianChart.HorizontalAxis
>
<
telerik:RadCartesianChart.VerticalAxis
>
<
telerik:LinearAxis
/>
</
telerik:RadCartesianChart.VerticalAxis
>
<
telerik:RadCartesianChart.SeriesProvider
>
<
telerik:ChartSeriesProvider
Source
=
"{Binding Path=Series}"
>
<
telerik:ChartSeriesProvider.SeriesDescriptors
>
<
telerik:CategoricalSeriesDescriptor
ItemsSourcePath
=
"Data"
TypePath
=
"SeriesType"
CategoryPath
=
"Date"
ValuePath
=
"Value"
/>
</
telerik:ChartSeriesProvider.SeriesDescriptors
>
</
telerik:ChartSeriesProvider
>
</
telerik:RadCartesianChart.SeriesProvider
>
</
telerik:RadCartesianChart
>
</
Grid
>
</
Window
>
MainWindow.xaml.cs:
And ViewModel.cs:
using
System;
using
System.Collections.ObjectModel;
using
Telerik.Windows.Controls.ChartView;
// Should not have this in VM layer!
namespace
TwoDynamic
{
public
class
DataPoint
{
public
DateTime Date {
get
;
set
; }
public
double
Value {
get
;
set
;}
}
public
abstract
class
SeriesBase
{
public
abstract
ObservableCollection<DataPoint> Data {
get
;
set
; }
// This DOES NOT BELONG in the ViewModel! TypePath really needs
// a converter so this can provide a generic type, and have the
// Telerik-specific type supplied in the View layer.
public
abstract
Type SeriesType {
get
; }
}
public
class
PointData: SeriesBase
{
public
override
Type SeriesType {
get
{
return
typeof
(BarSeries); } }
public
override
ObservableCollection<DataPoint> Data {
get
;
set
; }
}
public
class
LineData : SeriesBase
{
public
override
Type SeriesType {
get
{
return
typeof
(LineSeries); } }
public
override
ObservableCollection<DataPoint> Data {
get
;
set
; }
}
public
class
ViewModel
{
private
Random _Random;
private
ObservableCollection<SeriesBase> _Series;
public
ObservableCollection<SeriesBase> Series {
get
{
return
_Series; } }
public
ViewModel()
{
_Random =
new
Random();
_Series =
new
ObservableCollection<SeriesBase>();
// In reality there would be a variable number of these.
_Series.Add(
new
PointData() { Data = GenerateSomeData() });
_Series.Add(
new
PointData() { Data = GenerateSomeData() });
// I can either add PointData items, or LineData items, but not both
//_Series.Add(new LineData() { Data = GenerateSomeData() });
//_Series.Add(new LineData() { Data = GenerateSomeData() });
}
private
ObservableCollection<DataPoint> GenerateSomeData()
{
ObservableCollection<DataPoint> newCollection =
new
ObservableCollection<DataPoint>();
for
(
int
i = 0; i < 10; i++)
newCollection.Add(
new
DataPoint() { Date =
new
DateTime(2012, 12, 31).AddDays(i), Value = _Random.Next(100) });
return
newCollection;
}
}
}
My problem #1 is that in ViewModel, I can add any number of EITHER LineData OR PointData items to the list and it all works fine. However, even though they're both SeriesBase types which is what is exposed in the collection, if I add both it throws the exception:
My real LineData and PointData classes are of course much more complicated, and have lots of distinct functionality relevant to the actual data that is being displayed. I have worked around this by creating an adapter class that can hold either of these types of objects, and whose properties return the contained object's values, but this is a pretty ugly hack.
The second issue I think you already understand, and that is that there should be no references to Telerik types in the ViewModel, but there's no (clean) way to use the TypePath setting without doing so (thus the need for the converter).
Does that clear things up?
Thanks,
Louis