1
votes

I'm struggling with live charts. I'm using WPF.

I want to build a bar chart that displays the number of members in a Karate Club by belt color. One of my learning projects.

Following their docs: https://lvcharts.net/App/examples/v1/wpf/Basic%20Column

I am getting an error in xaml:

d:DataContext="{d:DesignInstance local:Charts}" 'The name "Charts" does not exist in namespace "clr-namespace:KarateClub" '

and

LabelFormatter="{Binding Formatter}" 'Method Formatter not found in type Charts'

If I remove the DataContext code the graph displays but it doesn't use any of my values. I must be missing how to link the XAML code to the C# code...? Have I got the class/namespace path wrong?

My XAML Code:

<UserControl x:Class="KarateClub.Charts"
             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:local="clr-namespace:KarateClub"
             xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
             mc:Ignorable="d" 
             d:DesignHeight="400" d:DesignWidth="1000" d:DataContext="{d:DesignInstance local:Charts}" >

    <Grid Background="White" Width="1000" Height="550">
        <Grid Background="White" Margin="33,45,239,170">
            <lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Left">
                <lvc:CartesianChart.AxisX>
                    <lvc:Axis Title="Belts" Labels="{Binding Labels}"></lvc:Axis>
                </lvc:CartesianChart.AxisX>
                <lvc:CartesianChart.AxisY>
                    <lvc:Axis Title="Members" LabelFormatter="{Binding Formatter}"></lvc:Axis>
                </lvc:CartesianChart.AxisY>
            </lvc:CartesianChart>
        </Grid>
    </Grid>
</UserControl>

My C# Code:

using System;
using System.Windows.Controls;
using LiveCharts;
using LiveCharts.Wpf;

namespace KarateClub
{
    public partial class Charts : UserControl
    {

        public SeriesCollection SeriesCollection { get; set; }
        public string[] Labels { get; set; }
        public Func<double, string> Formatter { get; set; }


        public Charts()
        {
            InitializeComponent();

            SeriesCollection = new SeriesCollection
            {
                new ColumnSeries
                {
                    Title = "2020",
                    Values = new ChartValues<double> { 1, 5, 3, 5, 7, 3, 9, 2, 3 }
                }
            };

            Labels = new[] { "White", "Yellow", "Orange", "Green", "Blue", "Purple", "Brown", "Red", "Black" };
            Formatter = value => value.ToString("N");

            DataContext = this;

        }
    }
}
2

2 Answers

1
votes

You are currently using a design-time instance of Charts, which is generated by the designer. This instance is auto-generated and doesn't contain any data. This is the default behavior, which is controlled by the IsDesignTimeCreatable property of the markup extension DesignInstanceExtension. By default IsDesignTimeCreatable returns false, which directs the designer to create a fake instance using reflection (bypassing any constructor).

To use a design-time instance of the specified type which is properly constructed, you have to set this property explicitly to true:

<UserControl x:Class="KarateClub.Charts"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:KarateClub"
             d:DataContext="{d:DesignInstance local:Charts, IsDesignTimeCreatable=True}" >
  ...
</UserControl>

Now the designer will create an instance using the constructor instead of using reflection.

Apparently this Blend design-time attributes are not well documented. To learn more see Microsoft Docs: Design-Time Attributes in the Silverlight Designer

0
votes

The example you are following does not say d:DataContext="{d:DesignInstance local:Charts}".

it says d:DataContext="{d:DesignInstance local:BasicColumn}".