SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and now iOS Charting & Android Chart Components


I have been adding annotations to a chart as per your example with a few modifications. My annotations collection is updated from the constructor and from an OnLoad handler but not after this.

Please could you have a look at the attached example. It appears that when elements are added from the constructor and OnLoad, OnLabelsSourceChanged is called but the annotationCollection is not updated because the ParentSurface is null. They are later updated by the call to OnParentSurfaceRendered. Later when another annotation is added using the Add button OnLabelsSourceChanged is not called, the chart can be updated however by double clicking which causes OnParentSurfaceRendered to be called.

Many Thanks

  • You must to post comments

Hello Dai,

I was able to make this work with a small modification to your example code. You have a nicely structured MVVM application there by the way 🙂

So – you created a class called AnnotationCreationModifier, which was binding to ObservableCollection<ReportTag> in your view-model. In the OnParentSurfaceRendered event you are recreating the annotations on the scichartsurface.

Ok that’s good so far, but when adding a ReportTag annotation to the collection it doesn’t update, right?

In the AnnotationCreationModifier code you need to subscribe to the ObservableCollection&;tReportTag>.CollectionChanged event and rebuild your annotations there. Also I would advise against re-buiding annotations on each re-draw. This can cause performance problems, since adding an annotation could in fact trigger a redraw!

Please find the updated AnnotationModifier code below. this should work fine if you replace it in your application:

    /// The CustomAnnotationChartModifiers provides a bridge between ViewModel and SciChartSurface, where we can 
    /// access the Labels (via data binding) as well as the SciChart API to add, remove and manipulate annotations
    /// </summary>
    public class AnnotationChartModifier : ChartModifierBase
        public static readonly DependencyProperty LabelsSourceProperty = DependencyProperty.Register("LabelsSource", typeof(ObservableCollection<ReportTag>), typeof(AnnotationChartModifier), new PropertyMetadata(null, OnLabelsSourceChanged));

        ObservableCollection<ReportTag> _labelsSource = new ObservableCollection<ReportTag>();

        public ObservableCollection<ReportTag> LabelsSource
            get { return (ObservableCollection<ReportTag>)GetValue(LabelsSourceProperty); }
            set { SetValue(LabelsSourceProperty, value); }

        // Get a notification when new labels are set.
        private static void OnLabelsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            var modifier = (AnnotationChartModifier)d;
            ObservableCollection<ReportTag> newValue = e.NewValue as ObservableCollection<ReportTag>;
            if (newValue == null) return;

            // NOTE1: You were not subscribing to CollectionChanged. This is where you should 
            // rebuild annotations. 
            // For a truly efficient AnnotationChartModifier implementation, you should 
            // listen to the CollectionChanged arguments and only add new annotations, or 
            // remove old ones, or clear all only when the collection is cleared. 
            newValue.CollectionChanged += (s, arg) => modifier.RebuildAnnotations();


        // NOTE2: 
        // No need to rebuild annotations on render. In fact this is 
        // inefficient. The AnnotationCollection is designed to allow you to add
        // annotations once and it will automatically re-position them in chart
        // space as the chart is resized or VisibleRange changes
//        public override void OnParentSurfaceRendered(SciChartRenderedMessage e)
//        {
//            base.OnParentSurfaceRendered(e);
//            if (ParentSurface != null && LabelsSource != null)
//            {
//                RebuildAnnotations();
//            }
//        }

        // Recreate all annotations
        private void RebuildAnnotations()
            if (base.ParentSurface != null && LabelsSource != null)
                // Take a look at the base class, ChartModifierBase for a wealth of API 
                // methods and properties to manipulate the SciChartSurface
                var annotationCollection = base.ParentSurface.Annotations;

                // NOTE3: See note(1) above. Don't clear/re-add all per frame. 
                // If you have lots of annotations its more efficient to add only new ones etc... 

                foreach (var item in LabelsSource)
                    //        annotationCollection.Add(new CustomTextAnnotation() { DataContext = item });
                    TextAnnotation anno = new TextAnnotation
                          DataContext = item,
                          HorizontalAnchorPoint = HorizontalAnchorPoint.Center,
                          VerticalAnchorPoint = VerticalAnchorPoint.Bottom,
                          FontSize = 11.0,
                          ToolTip = item.LabelToolTip,
                          Text = item.LabelText,
                          X1 = item.X,
                          Y1 = item.Y



Thanks and regards,

  • Dai
    Hi Andrew, Many thanks, obvious when you know the answer. Regards Dai
  • Andrew
    No probs! Glad it's working for you now :)Andrew
  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.