2

I have created a composite annotation (named PeakAnnotation) that consists of four elements: two VerticalLineAnnotations, a BoxAnnotation, and a TextAnnotation. When I first add the annotation, everything appears correctly. However, when I change between tabs in my TabControl... the BoxAnnotation disappears. The box will reappear when I move the composite annotation a few pixels by dragging it with the cursor.

I have tried calling ZoomExtents() and InvalidateElement(), but does not fix the issue.

I've created a simple app to reproduce the issue in a simple minimal way.

PeakAnnotation.xaml

<s:CompositeAnnotation x:Class="WpfPresentation.Views.PeakAnnotation"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
                Canvas.ZIndex="1" 
                DragDirections="XDirection"
                ResizeDirections="XDirection"
                IsEditable="True">

<s:CompositeAnnotation.Annotations>
    <s:VerticalLineAnnotation CoordinateMode="Relative" Stroke="#FFBADAFF" StrokeThickness="2" X1="0" X2="0" Y1="0" Y2="1"/>
    <s:VerticalLineAnnotation CoordinateMode="Relative" Stroke="#FFBADAFF" StrokeThickness="2" X1="1" X2="1" Y1="0" Y2="1"/>
    <s:BoxAnnotation x:Name="box" Opacity="0.2" CornerRadius="2" Background="#FFBADAFF" BorderBrush="#1964FF" CoordinateMode="Relative" X1="0" X2="1" Y1="0" Y2="1"/>
    <s:TextAnnotation x:Name="AnnotationTextLabel" CoordinateMode="Relative" X1="0" Y1="0.95" FontSize="12" Foreground="White"/>
</s:CompositeAnnotation.Annotations>

</s:CompositeAnnotation>

PeakAnnotation.xaml.cs

public partial class PeakAnnotation : CompositeAnnotation
{
    public PeakAnnotation()
    {

    }
    
    public PeakAnnotation(string annotationText)
    {
        InitializeComponent();
        AnnotationTextLabel.Text = annotationText;
    }

    public string StyleKey { get; set; }

    public Type ViewType => throw new NotImplementedException();
}

MainViewModel.cs

public MainViewModel()
    {
        ChartTitle = "Testing";

        Annotations = new AnnotationCollection();

        var myAnnotation = new PeakAnnotation("My Annotation Title")
        {
            X1 = 40,
            X2 = 50,
            Y1 = 0,
            Y2 = 100
        };

        Annotations.Add(myAnnotation);
    }
    public string ChartTitle { get; set; }
    public AnnotationCollection Annotations { get; set; }
}

MainWindow.xaml

<Window x:Class="SciChartTesting.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:SciChartTesting" xmlns:s="http://schemas.abtsoftware.co.uk/scichart"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Window.Resources>
    <local:MainViewModel x:Key="MainViewModel"/>
</Window.Resources>

<Grid DataContext="{StaticResource MainViewModel}">
    <TabControl>
        <TabItem Header="TabOne">
            <Label Content="This is TabOne"/>
        </TabItem>
        <TabItem Header="TabTwo">
            <s:SciChartSurface ChartTitle="{Binding ChartTitle}" Annotations="{Binding Annotations}">
                <s:SciChartSurface.XAxis>
                    <s:NumericAxis VisibleRange="0,100"/>
                </s:SciChartSurface.XAxis>
                <s:SciChartSurface.YAxis>
                    <s:NumericAxis VisibleRange="0,100"/>
                </s:SciChartSurface.YAxis>
            </s:SciChartSurface>
        </TabItem>
    </TabControl>
</Grid>

Working annotation: working example

Broken annotation: enter image description here

Kyle Williamson
  • 2,251
  • 6
  • 43
  • 75
  • 2
    The `TabControl` only uses a single shared `ContentPresenter` to display the contents of a `TabItem`. This means it removes the content between tab navigation. Rendering details like adorner layers are not preserved. You have to explicitly redraw the annotation element on content load e.g. using a trigger. – BionicCode Jul 09 '20 at 06:33
  • Or you can create your own tab control, which only hides elements which should not be visible – Maciek Świszczowski Jul 14 '20 at 13:04
  • @BionicCode If you would like the bounty. Post your message as an answer. The solution seems to be recreating the annotation element when the tab is changed. – Kyle Williamson Jul 15 '20 at 19:36
  • Alright. Thank you. Yes, that's the correct solution. You have to redraw stateful visuals like adorners of validation error templates etc. This is some unexpected behaviour. But it makes a lot of sense. – BionicCode Jul 15 '20 at 20:23

1 Answers1

1

The TabControl only uses a single shared ContentPresenter to display the contents of a TabItem. This means it completely removes the content from the visual tree between tab navigation. Rendering details like adorner layers or state of triggers are not preserved. You have to explicitly redraw the annotation element on content load e.g. using a trigger.

BionicCode
  • 1
  • 4
  • 28
  • 44