I am using UI for UWP from telerik to draw a chart. https://github.com/telerik/UI-For-UWP
I am trying to data bind annotations and have them dynamically displayed.
I have bound one annotations like this:
View
<chart:RadCartesianChart x:Name="OhlcChart" PaletteName="DefaultLightSelected" Grid.Row="1">
<chart:RadCartesianChart.VerticalAxis>
<chart:LinearAxis/>
</chart:RadCartesianChart.VerticalAxis>
<chart:RadCartesianChart.HorizontalAxis>
<chart:DateTimeCategoricalAxis LabelFormat="{}{0,0:dd/MM}"/>
</chart:RadCartesianChart.HorizontalAxis>
<chart:RadCartesianChart.Annotations>
<chart:CartesianCustomLineAnnotation
HorizontalFrom="{x:Bind ViewModel.Annotations[0].Date1}"
VerticalFrom="{x:Bind ViewModel.Annotations[0].Value1}"
HorizontalTo="{x:Bind ViewModel.Annotations[0].Date2}"
VerticalTo="{x:Bind ViewModel.Annotations[0].Value2}"
/>
</chart:RadCartesianChart.Annotations>
</chart:RadCartesianChart.Annotations>
</chart:RadCartesianChart>
View Model
public class ChartViewModel : ViewModelBase
{
public class DataItem
{
public DateTime Date1 { get; set; }
public double Value1 { get; set; }
public DateTime Date2 { get; set; }
public double Value2 { get; set; }
}
public DataItem [] Annotations { get; }
}
How can I bind an enumerable amount of annotations like this:
public class ChartViewModel : ViewModelBase
{
public class DataItem
{
public DateTime Date1 { get; set; }
public double Value1 { get; set; }
public DateTime Date2 { get; set; }
public double Value2 { get; set; }
}
public DataItem [] Annotations { get; }
}
RadCartesianChart.Annotations
does not have an ItemTemplate property like ListView and GridView.
I want to bind my viewmodel such that there is a CartesianCustomLineAnnotation
for each item in my view model array.
I was able to solve my problem like this
public class ViewModel : ViewModelBase
{
public Angle[] Angles
{
get => _angles;
set => SetProperty(ref _angles, value);
}
public class Angle
{
public DateTime Date1 { get; set; }
public double Value1 { get; set; }
public double Value2 { get; set; }
public DateTime Date2 { get; set; }
}
}
code behind
public class ChartPage : Page
{
private static readonly DependencyProperty AnnotationsProperty =
DependencyProperty.RegisterAttached(
"AnnotationsProperty",
typeof(Angle[]),
typeof(ChartPage),
new PropertyMetadata(Array.Empty<Angle>(), OnAnnotationsChanged));
public static void OnAnnotationsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var chart = (RadCartesianChart)d;
var angles = e.NewValue as Angle[];
chart.Annotations.Clear();
if (angles == null || angles.Length == 0)
{
return;
}
angles
.Select(x => new CartesianCustomLineAnnotation
{
HorizontalFrom = x.Date1,
HorizontalTo = x.Date2,
VerticalFrom = x.Value1,
VerticalTo = x.Value2
})
.ToList()
.ForEach(chart.Annotations.Add);
}
public ChartPage()
{
InitializeComponent();
this.OhlcChart.SetBinding(AnnotationsProperty, new Binding
{
Path = new PropertyPath(nameof(ChartViewModel.Angles)),
Mode = BindingMode.OneWay,
});
}
}
I hope this is the correct approach and doesn't memory leak.