1

I am using trial version of SciChart and doing some tests.

I need to bring scroll bar on top of X axis.

After some research and parsing visual tree, I am planning to change style of SciChartSurface and replace axis and scroll bar, which are placed inside stack panel.

Is this right solution? If AxisAlignment is Top, visual tree may differ. If this is right way to go, where can I find style of surface? Bland does not recognize chart and I can't use it.

Samvel Siradeghyan
  • 3,523
  • 3
  • 30
  • 49

1 Answers1

1

I was playing around with this and it is possible to achieve a scrollbar above an XAxis by templating the axis control itself.

Here is the default control template for the AxisBase control (SciChart v4)

<ControlTemplate TargetType="axes:AxisBase">
    <Border Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            ap:Device.SnapsToDevicePixels="True">

        <StackPanel x:Name="PART_AxisContainer"
                    HorizontalAlignment="Stretch"
                    VerticalAlignment="Stretch"
                    Orientation="{Binding AxisAlignment, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay, Converter={StaticResource AxisAlignmentToAxisOrientationConverter}, ConverterParameter=Inverse}"
                    ap:Device.SnapsToDevicePixels="True"
                    apc:AxisLayoutHelper.AxisAlignment="{Binding AxisAlignment, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">

            <Grid HorizontalAlignment="Stretch"
                  VerticalAlignment="Stretch"
                  Canvas.ZIndex="1"
                  ap:Device.SnapsToDevicePixels="True"
                  apc:AxisLayoutHelper.IsInsideItem="True">

                <themes:AxisPanel x:Name="PART_AxisCanvas"
                                  AxisAlignment="{TemplateBinding AxisAlignment}"
                                  Background="Transparent"
                                  DrawLabels="{TemplateBinding DrawLabels}"
                                  DrawMajorTicks="{TemplateBinding DrawMajorTicks}"
                                  DrawMinorTicks="{TemplateBinding DrawMinorTicks}"
                                  IsLabelCullingEnabled="{TemplateBinding IsLabelCullingEnabled}"
                                  MajorTickLineStyle="{TemplateBinding MajorTickLineStyle}"
                                  MinorTickLineStyle="{TemplateBinding MinorTickLineStyle}"
                                  ap:Device.SnapsToDevicePixels="True">

                    <Image x:Name="PART_AxisBitmapImage"
                           HorizontalAlignment="Stretch"
                           VerticalAlignment="Stretch"
                           Stretch="Fill"
                           ap:Device.SnapsToDevicePixels="True" />

                    <Grid x:Name="PART_LabelsCanvas" Margin="{Binding LabelToTickIndent, RelativeSource={RelativeSource FindAncestor, AncestorType=themes:AxisPanel}, Mode=OneWay}">
                        <themes:TickLabelAxisCanvas AutoFitMarginalLabels="{TemplateBinding AutoFitMarginalLabels}"
                                                    Background="Transparent"
                                                    ClipToBounds="False"
                                                    IsLabelCullingEnabled="{TemplateBinding IsLabelCullingEnabled}"
                                                    ap:Device.SnapsToDevicePixels="True" />
                        <themes:TickLabelAxisCanvas AutoFitMarginalLabels="{TemplateBinding AutoFitMarginalLabels}"
                                                    Background="Transparent"
                                                    ClipToBounds="False"
                                                    IsLabelCullingEnabled="{TemplateBinding IsLabelCullingEnabled}"
                                                    Visibility="Collapsed"
                                                    ap:Device.SnapsToDevicePixels="True" />
                    </Grid>

                    <labelProviders:AxisTitle Orientation="{TemplateBinding Orientation}"
                                              Style="{TemplateBinding TitleStyle}"
                                              Visibility="{Binding Content, RelativeSource={RelativeSource Self}, Converter={StaticResource CollapseIfNullOrEmptyStringConverter}}" />
                </themes:AxisPanel>

                <themes:ModifierAxisCanvas x:Name="PART_ModifierAxisCanvas"
                                           HorizontalAlignment="Stretch"
                                           VerticalAlignment="Stretch"
                                           ap:Device.SnapsToDevicePixels="True" />
            </Grid>

            <ContentPresenter Content="{TemplateBinding Scrollbar}" apc:AxisLayoutHelper.IsOutsideItem="True" />
        </StackPanel>
    </Border>
</ControlTemplate>

Here is the modified template (including converters)

<s:DateTimeAxis AxisAlignment="Bottom"
            AxisTitle="Top Axis"
            BorderThickness="0,0,0,1"
            Id="TopAxisId">
<s:DateTimeAxis.Resources>
    <s:AxisAlignmentToAxisOrientationConverter x:Key="AxisAlignmentToAxisOrientationConverter" />
    <s:CollapseIfNullOrEmptyStringConverter x:Key="CollapseIfNullOrEmptyStringConverter" />
</s:DateTimeAxis.Resources>
<s:DateTimeAxis.Template>
    <ControlTemplate TargetType="s:AxisBase">
        <Border Background="{TemplateBinding Background}"
        BorderBrush="{TemplateBinding BorderBrush}"
        BorderThickness="{TemplateBinding BorderThickness}"
        s:Device.SnapsToDevicePixels="True">

            <StackPanel x:Name="PART_AxisContainer"
                HorizontalAlignment="Stretch"
                VerticalAlignment="Stretch"
                Orientation="{Binding AxisAlignment, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay, Converter={StaticResource AxisAlignmentToAxisOrientationConverter}, ConverterParameter=Inverse}"
                s:Device.SnapsToDevicePixels="True"
                s:AxisLayoutHelper.AxisAlignment="{Binding AxisAlignment, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">

                <ContentPresenter Content="{TemplateBinding Scrollbar}" />

                <Grid HorizontalAlignment="Stretch"
              VerticalAlignment="Stretch"
              Canvas.ZIndex="1"
              s:Device.SnapsToDevicePixels="True"
              >

                    <s:AxisPanel x:Name="PART_AxisCanvas"
                              AxisAlignment="{TemplateBinding AxisAlignment}"
                              Background="Transparent"
                              DrawLabels="{TemplateBinding DrawLabels}"
                              DrawMajorTicks="{TemplateBinding DrawMajorTicks}"
                              DrawMinorTicks="{TemplateBinding DrawMinorTicks}"
                              IsLabelCullingEnabled="{TemplateBinding IsLabelCullingEnabled}"
                              MajorTickLineStyle="{TemplateBinding MajorTickLineStyle}"
                              MinorTickLineStyle="{TemplateBinding MinorTickLineStyle}"
                              s:Device.SnapsToDevicePixels="True">

                        <Image x:Name="PART_AxisBitmapImage"
                       HorizontalAlignment="Stretch"
                       VerticalAlignment="Stretch"
                       Stretch="Fill"
                       s:Device.SnapsToDevicePixels="True" />

                        <Grid x:Name="PART_LabelsCanvas" Margin="{Binding LabelToTickIndent, RelativeSource={RelativeSource FindAncestor, AncestorType=s:AxisPanel}, Mode=OneWay}">
                            <s:TickLabelAxisCanvas AutoFitMarginalLabels="{TemplateBinding AutoFitMarginalLabels}"
                                                Background="Transparent"
                                                ClipToBounds="False"
                                                IsLabelCullingEnabled="{TemplateBinding IsLabelCullingEnabled}"
                                                s:Device.SnapsToDevicePixels="True" />
                            <s:TickLabelAxisCanvas AutoFitMarginalLabels="{TemplateBinding AutoFitMarginalLabels}"
                                                Background="Transparent"
                                                ClipToBounds="False"
                                                IsLabelCullingEnabled="{TemplateBinding IsLabelCullingEnabled}"
                                                Visibility="Collapsed"
                                                s:Device.SnapsToDevicePixels="True" />
                        </Grid>

                        <s:AxisTitle Orientation="{TemplateBinding Orientation}"
                                          Style="{TemplateBinding TitleStyle}"
                                          Visibility="{Binding Content, RelativeSource={RelativeSource Self}, Converter={StaticResource CollapseIfNullOrEmptyStringConverter}}" />
                    </s:AxisPanel>

                    <s:ModifierAxisCanvas x:Name="PART_ModifierAxisCanvas"
                                       HorizontalAlignment="Stretch"
                                       VerticalAlignment="Stretch"
                                       s:Device.SnapsToDevicePixels="True" />
                </Grid>


            </StackPanel>
        </Border>
    </ControlTemplate>
</s:DateTimeAxis.Template>
<s:DateTimeAxis.Scrollbar>
    <s:SciChartScrollbar Margin="0 3 0 0" />
</s:DateTimeAxis.Scrollbar>
</s:DateTimeAxis>

This code includes the default control template of the AxisBase in SciChart but removes two critical attached properties: AxisLayoutHelper.IsOutsideItem / IsInsideItem. These properties are used to adjust the order of Axis vs, Scrollbar depending on alignment of the axis. Removing them, you can place the ContentPresenter for the scrollbar anywhere and it will stay put.

This is tested as working in v4 of SciChart WPF

Dr. Andrew Burnett-Thompson
  • 20,980
  • 8
  • 88
  • 178
  • 1
    Thanks for answer. I will use other solution, as have performance issues with current tick labels. I have about 100 major ticks, and as they re rendering as WPF without DirectX. Planning to move labels inside surface. – Samvel Siradeghyan Apr 14 '16 at 20:54
  • Hi Samvel, that is true, we create labels using WPF TextBlock which greatly simplifies things like drawing unicode text or font management (all of which have to be written in DirectX). Feel free to open another question if you have issues! – Dr. Andrew Burnett-Thompson Apr 15 '16 at 08:52