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

0
0

I’m developing an application where I need to generate a series of small chart “thumbnails” in a window. When the user clicks one, an equivalent full size chart is displayed in a separate window. There are several different types of chart (different data, interactivity, etc).

The thumbnail charts are quite small and have minimal formatting (e.g. no axis titles, grid lines, and so on), while the full size charts have more visual elements, and interactive functionality including modifiers, context menus, and other mouse event handlers. For this reason I’ve been using separate XAML for each chart’s thumb and full size version, but having two versions for each chart is becoming a maintenance issue as new chart types are added.

Certain elements are pretty similar between the two – particularly the and the (and YAxis), and I was wondering if there was a way to make these into resources, or if you can suggest some other way to achieve what I’m trying to do (i.e. XAML re-usability!).

I tried creating a resource dictionary with a style targeting “SciChartSurface”, then adding a setter for “RenderableSeries”, but it doesn’t like that as it’s an ObservableCollection.

  • You must to post comments
0
0

Hi Andy,

Why not use MVVM? YOu are right you should not create Reference Types in XAML resources, since they are shared between all types that use them.

E.g. the XAML

<SciChartSurface XAxis="{StaticResource SharedXAxis}" 
                           YAxis="{StaticResource SharedYAxis}"
                           RenderableSeries="{StaticResource RenderableSeries}"/>

Is not a good idea, since every ScichartSurface that uses these resources will share them!

DynamicResource is another idea because that means a new instance is created for each type that references them, but still its not ideal.

Perhaps the best idea is to use MVVM. For instance, your XAML becomes:

<SciChartSurface XAxis="{Binding XAxisInViewModel}" 
                           YAxis="{Binding YAxisInViewModel}"
                           RenderableSeries="{Binding RenderableSeriesInViewModel}"/>

You will need to create a ViewModel class with these properties and types exposed. Another idea to try is to template the entire SciChartSurface and re-use inside a content-control, e.g.

<DataTemplate x:Key="chartTemplate" DataType="ContentControl">
    <SciChartSurface XAxis="{Binding XAxisInViewModel}" 
                           YAxis="{Binding YAxisInViewModel}"
                           RenderableSeries="{Binding RenderableSeriesInViewModel}"/>
</DataTemplate>

<!-- repeated instantiation -->
<ContentControl Template="{StaticResource chartTemplate}"/>
<ContentControl Template="{StaticResource chartTemplate}"/>
<ContentControl Template="{StaticResource chartTemplate}"/>

Anyway I hope that gives you some ideas. The last idea is to create a custom UserControl which contains your chart & viewmodel pair and just have some properties to show/hide various parts (e.g. show/hide the axes, or gridlines).

Best regards,
Andrew

  • andyste1
    I am using MVVM but hadn't thought about binding the axis and RenderableSeries, although you could argue that you are introducing knowledge of the UI into the VM by doing this. I'll certainly explore the last one though - I haven't really touched on WPF user controls, so your last suggestion could be the way to go. Thanks for your help.
  • Andrew
    Yes its not ideal you are right, as Axis and RenderableSeries must be defined in the ViewModel. There is another way (or several other ways). MVVM needs a third class to create the idea pattern for these complex cases, such as a custom Behavior, or even a ChartModifier.In this example we use a ChartModifierBase derived class to act as a broker between ViewModel (containing LabelViewModel's) and SciChartSurface (containing Annotations), keeping view-specific code out of the Viewmodel. The same thing could be done with an attached behavior (or FrameworkElement derived class with attached property for bindings).However when choosing any design pattern its worth considering what you are gaining by using it, as well as time/complexity to implement vs. what would be the cost of not using it. In other words 'use the right tool for the job'!Hope that helps!Andrew
  • You must to post comments
0
0

Hi,

There is also another idea for you:

    <DataTemplate x:Key="MyXAxis">
        <s:NumericAxis ... />
    </DataTemplate>
    <Style ... TargetType="s:SciChartSurface">
        <Setter Property="XAxis" Value="{Binding Source={StaticResource MyXAxis}, Converter={StaticResource DataTemplateToObjectConverter}}" />
        <Setter Property="YAxis" Value="{Binding Source={StaticResource MyYAxis}, Converter={StaticResource DataTemplateToObjectConverter}}" />
        <Setter Property="ChartModifier" Value="{Binding Source={StaticResource MyChartModifier}, Converter={StaticResource DataTemplateToObjectConverter}}" />
    </Style>

..and converter just calls dataTemplate.LoadContent():

    public class DataTemplateToObjectConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var template = (DataTemplate) value;

            return template.LoadContent() as FrameworkElement;
        }
....

Best regards,
Yuriy

  • andyste1
    That's useful thanks, I'll look into that.
  • You must to post comments
Showing 2 results
Your Answer

Please first to submit.