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

Welcome to the SciChart Community Forums!

Please use the forums below to ask questions about SciChart. Take a moment to read our Question asking guidelines on how to ask a good question and our support policy

We also have a tag=SciChart on Stackoverflow.com where you can earn rep for your questions!

0
0

Hi,
I’ve created a custom annotation and have set it’s .IsEditable property in code so the user can reposition it. I have two issues:
1.I want the user to be able to resize the “PPZLine” in the X direction, but I can’t figure out how to get the anchor points to appear.

  1. I want to be able to see the chart data that the annotation is covering. I tried setting AnnotationCanvas = BelowChart, but then I couldn’t move the annotation or get any annotation mouse handlers to trigger.

Here’s the annoation’s xaml:

<s:CustomAnnotation x:Class="CinchV2DemoWPF.Views.SciChart.PPZView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:CinchV2="clr-namespace:Cinch;assembly=Cinch.WPF"
             xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
             xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:s="clr-namespace:Abt.Controls.SciChart;assembly=Abt.Controls.SciChart.Wpf" 
             meffed:ViewModelLocator.ViewModel="PPZViewModel"

             X1="{Binding X1}"
             Y1="{Binding Y1}"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

    <!-- price line must use margin 0,0 or obj will not be visible-->
        <s:BoxAnnotation Name="LongEntryMarker" Grid.Row="0"
                       Width="20"    Height="10"  Background="DarkViolet" Margin="0,0"  VerticalAlignment="Top" 
                         HorizontalAlignment="Right"
                         >
        </s:BoxAnnotation>

        <!-- long marker line MouseRightButtonDown="LongEntryMarker_OnMouseRightButtonDown"-->
        <s:BoxAnnotation Name="PPZLine" Grid.Row="1"
                       Width="150"    Height="5"  Background="red" Margin="0,0"  VerticalAlignment="Top" 
                         >
        </s:BoxAnnotation>
</Grid>
</s:CustomAnnotation>
  • You must to post comments
0
0

Hello there,

Hmmm… the CustomAnnotation is an AnchorPointAnnotation meaning it expects to have a single X1Y1 point (not X1Y1, X2Y2 pair). It can only be positioned by a single X,Y coordinate plus optional Width, Height.

It might be necessary if you want to resize all four edges to re-template a BoxAnnotation, here is the Control Template:

    <!--  Annotations  -->
    <Style x:Key="AnnotationBaseStyle" TargetType="a:AnnotationBase">
        <Style.Setters>
            <Setter Property="IsTabStop" Value="False" />
        </Style.Setters>
    </Style>

    <!--  BoxAnnotation  -->
    <Style BasedOn="{StaticResource AnnotationBaseStyle}" TargetType="a:BoxAnnotation">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="a:BoxAnnotation">
                    <Border x:Name="PART_BoxAnnotationRoot"
                            Margin="{TemplateBinding Margin}"
                            Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}"
                            CornerRadius="{TemplateBinding CornerRadius}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

If you adjust that (e.g. put a child of Border with your custom annotation content in it) and apply to specific BoxAnnotations in your application (using an x:Key on the style) you should be able to get a four-point resizable custom annotation.

Let me know if that works!

Re: The other issue, cannot move an annotation below the series, oops – I have logged this as a bug for investigation. My apologies for that.

Best regards,
Andrew

  • You must to post comments
0
0

Andrew,
I’ve got the following retemplated resizable boxannotation working! The box annotation is composed of 2 rectangles.
The new template in App.xaml is:

 &lt;!--  Annotations ************************************************************************************* --&gt;
&lt;Style x:Key=&quot;AnnotationBaseStyle&quot; TargetType=&quot;s:AnnotationBase&quot;&gt;
    &lt;Style.Setters&gt;
        &lt;Setter Property=&quot;IsTabStop&quot; Value=&quot;False&quot; /&gt;
    &lt;/Style.Setters&gt;
&lt;/Style&gt;

&lt;!--  BoxAnnotation - applies to all BoxAnnotations, since there is no x:key --&gt;
&lt;Style BasedOn=&quot;{StaticResource AnnotationBaseStyle}&quot;  x:Key=&quot;PPZBox&quot; TargetType=&quot;s:BoxAnnotation&quot;&gt;
    &lt;Setter Property=&quot;Template&quot;&gt;
        &lt;Setter.Value&gt;
            &lt;ControlTemplate TargetType=&quot;s:BoxAnnotation&quot;&gt;
                &lt;Border x:Name=&quot;PART_BoxAnnotationRoot&quot;
                    Margin=&quot;{TemplateBinding Margin}&quot;
                    Background=&quot;{TemplateBinding Background}&quot;
                    BorderBrush=&quot;{TemplateBinding BorderBrush}&quot;
                    BorderThickness=&quot;{TemplateBinding BorderThickness}&quot;
                    CornerRadius=&quot;{TemplateBinding CornerRadius}&quot; 
                            &gt;

                    &lt;Grid&gt;
                        &lt;Grid.RowDefinitions&gt;
                            &lt;RowDefinition Height=&quot;10&quot;/&gt;
                            &lt;RowDefinition Height=&quot;*&quot;/&gt;
                        &lt;/Grid.RowDefinitions&gt;

                                &lt;Grid.ColumnDefinitions&gt;
                                    &lt;ColumnDefinition Width=&quot;*&quot;/&gt;
                                    &lt;ColumnDefinition Width=&quot;15&quot;/&gt;
                                &lt;/Grid.ColumnDefinitions&gt;

                                &lt;!-- price line must use margin 0,0 or obj will not be visible--&gt;
                        &lt;Rectangle Name=&quot;PPZLine&quot; Grid.Row=&quot;0&quot; Grid.Column=&quot;0&quot;
                                       Width=&quot;Auto&quot;    Height=&quot;10&quot;  Fill=&quot;red&quot;  VerticalAlignment=&quot;Top&quot; 
                                         &gt;
                        &lt;/Rectangle&gt;
                                &lt;Rectangle Name=&quot;LongEntryMarker&quot; Grid.Row=&quot;0&quot; Grid.Column=&quot;1&quot;
                                       Width=&quot;15&quot;    Height=&quot;10&quot;  Fill=&quot;SeaGreen&quot; Margin=&quot;0,0&quot; 
                                         HorizontalAlignment=&quot;Right&quot; 
                                         &gt;
                        &lt;/Rectangle&gt;

                        &lt;!-- long marker line MouseRightButtonDown=&quot;LongEntryMarker_OnMouseRightButtonDown&quot;--&gt;
                    &lt;/Grid&gt;

                &lt;/Border&gt;

            &lt;/ControlTemplate&gt;
        &lt;/Setter.Value&gt;
    &lt;/Setter&gt;
&lt;/Style&gt;

The view that uses the new boxannotation template,PPZView.xaml, is:

<cw:PPZAnnotation x:Class="CinchV2DemoWPF.Views.SciChart.PPZView"
xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml&quot;
xmlns:mc=" http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
xmlns:d=" http://schemas.microsoft.com/expression/blend/2008&quot;
xmlns:local="clr-namespace:Cinch;assembly=Cinch.WPF"
xmlns:meffed="clr-namespace:MEFedMVVM.ViewModelLocator;assembly=MEFedMVVM.WPF"
xmlns:Interactivity="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:s="clr-namespace:Abt.Controls.SciChart;assembly=Abt.Controls.SciChart.Wpf"
xmlns:cw="clr-namespace:CinchV2DemoWPF"
meffed:ViewModelLocator.ViewModel="PPZViewModel"
Style="{StaticResource PPZBox}"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="300">
</cw:PPZAnnotation>

Now the thing I can’t figure out is how to access the rectangle named ‘LongEntryMarker’ so I can add mouse handlers. What I want to do in the PPZAnnotationViewModel is:
view.LongEntryMarker.MouseRightButtonDown += LongMouseDownHander;
I’ve got access to the view, but I need to somehow add the rectangle called ‘LongEntryMarker’ as a view property.

thanks in advance! I’m still inexperienced with xaml.

  • Andrew
    For somebody whose inexperienced with XAML you've done pretty well! Control templating is an advanced topic!Well done, I'm really glad this works as we didn't think of it until you pointed out the limitation with CustomAnnotation, so its great to know it can be used.Ok to get access to the annotation? I would suggest handling MouseRightButtonDown in the code-behind of your PPZAnnotation control and then passing up the event to a parent. Ideally you shouldn't handle mouse-event-handlers in a viewmodel, its better to handle these in View-code (since they are view related), then pass the result to a ViewModel.Or ... if you want you can actually bind an event to a ViewModel, using syntax like this:<PPZAnnotation> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDown"> <cmd:EventToCommand Command="{Binding MouseDownCommand, Mode=OneWay}" CommandParameter="{Binding}" /> </i:EventTrigger> </i:Interaction.Triggers> </PPZAnnotation>The EventTrigger comes from MVVM Lite, but there are many other frameworks which provide Event-To-Command.Next you will need to expose an ICommand in your ViewModelpublic class MyViewModel : INotifyPropertyChanged { // ...public ICommand MouseDownCommand { get { return new DelegateCommand(() => HandleMouseDown()); } } }Finally you need to make sure the DataContext of your PPZAnnotation is equal to the viewmodel that hosts the command. How to do this? You can either set the DataContext on all annotations as you create them, or, you can use a RelativeSource binding to bind PPZAnnotation to a parent classes' view model. You can learn more about RelativeSource binding here.Hope this helps!Andrew
  • tecman234
    I've used eventToCommand binding before, but I'm trying to capture the mouse event only for the rectangle called 'LongEntryMarker', not the entire PPZAnnotation. I can't put the eventToCommand in the app.xaml where I've retemplated the box annotation, because there isn't any datacontext in the template. If put the eventToCommand in the PPZAnnotation xaml, I can't figure out out how to reference 'LongEntryMarker'. thanks.
  • Andrew
    Thats the magic of binding, you don't need a datacontext. Just do an EventToCommand binding and use RelativeSource FindAncestor to walk up the visual tree.Or ... if you want to debug it in code,handle OnMouseDown in code-behind of your custom annotation and use the VisualTreehHelper to find a parent of type SciChartSurface, then get its datacontext and call a method manually in the ViewModel (by getting and casting DataContext).That should do it :-)Andrew
  • tecman234
    Andrew, thanks for pointing out that I could just include the eventToCommand in a template. I'm using Cinch mvvm so I used EventToCommandTrigger, but I didn't need the Relativesource because cinch automagically binds the use of the template to the current view model. Now everything is working on the custom box annotation.thanks for all of your help with this!
  • Andrew
    Sounds like you've done something really cool (that we didn't think about in our examples) - made a custom box annotation! Well done :)and for a beginner in XAML too!- Andrew
  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.