xceedsoftware/Xceed-Toolkit-for-.NET-MAUI

Data Binding for DataPointsSource property of Chart does not work

Closed this issue · 1 comments

here is the reproducing repo https://github.com/HakamFostok/ChartMVVM

The DataPointsSource of the Chart does not show, but if the DataPoints are created by hand then it shows

The following does not work

<xctk:Chart x:Name="MyChart">
    <xctk:Chart.HorizontalAxis>
        <xctk:Axis TickLabelType="Text" />
    </xctk:Chart.HorizontalAxis>
    <xctk:Chart.Series>

        <!-- This does NOT work -->
        <xctk:Series DataPointsSource="{Binding Path=Points}">
        </xctk:Series>

    </xctk:Chart.Series>

</xctk:Chart>

image

But the following code does work

    <xctk:Chart x:Name="MyChart">
        <xctk:Chart.HorizontalAxis>
            <xctk:Axis TickLabelType="Text" />
        </xctk:Chart.HorizontalAxis>
        <xctk:Chart.Series>
            <!-- This works -->
            <xctk:Series x:Name="kug">
                <xctk:Series.DataPoints>
                    <xctk:DataPoint Text="0" Y="10" />
                    <xctk:DataPoint Text="1" Y="12" />
                    <xctk:DataPoint Text="2" Y="15" />
                    <xctk:DataPoint Text="3" Y="1" />
                    <xctk:DataPoint Text="4" Y="6" />
                    <xctk:DataPoint Text="5" Y="30" />
                    <xctk:DataPoint Text="6" Y="11" />
                </xctk:Series.DataPoints>
            </xctk:Series>
        </xctk:Chart.Series>

    </xctk:Chart>

image

Sorry for bothering you so much, I am keep opening issues on this Repo, but I was trying with this for 3 days

Again thank you very much

Hello @HakamFostok ,

No problem for you to ask questions, we are here to help :-)

When DataPoints are created by hand, like:
<xctk:Series x:Name="FirstSeries"> <xctk:Series.DataPoints> <xctk:DataPoint Text="0" Y="44" /> <xctk:DataPoint Text="1" Y="64" /> <xctk:DataPoint Text="2" Y="60" /> <xctk:DataPoint Text="3" Y="32" /> </xctk:Series.DataPoints> </xctk:Series>

it will work because the DataPoints are explicitly defined, with their Text and Y properties(in your sample, the HorizontalAxis is using TickLabelType="Text" ).

When using the Series.DataPointsSource property, you have to think about 2 things:
-A Series is not part of the Visual tree, its just an info object so it won't inherit the BindingContext.
-The Series.DataPointsSourceBindingInfos must be set to tell the Series which property on the userObject will be used for X/Text on the Axis and which property on the userObject will be used for the Y on the Axis.

So, from your sample, here are 2 solutions:

  1. Use a collection source defined in ContentPage.Resources:
    `<ContentPage.Resources>
    <sample:Persons x:Key="Persons"/>
    </ContentPage.Resources>
    ...
    xctk:Chart.HorizontalAxis
    <xctk:Axis TickLabelType="Text" />
    </xctk:Chart.HorizontalAxis>
    ....
    <xctk:Series DataPointsSource="{Binding Source={StaticResource Persons}, Path=PersonList}">
    xctk:Series.DataPointsSourceBindingInfos
    <xctk:BindingInfos DataPointPropertyName="Text"
    UserObjectPropertyName="Name" />
    <xctk:BindingInfos DataPointPropertyName="Y"
    UserObjectPropertyName="Skill" />
    </xctk:Series.DataPointsSourceBindingInfos>
    </xctk:Series>

public class Person
{
#region Properties

#region Age

public int Age
{
get
{
return m_age;
}
set
{
if( m_age != value )
{
m_age = value;
}
}
}

private int m_age;

#endregion

#region Name

public string Name
{
get
{
return m_name;
}
set
{
if( m_name != value )
{
m_name = value;
}
}
}

private string m_name;

#endregion

#region Skill

public double Skill
{
get
{
return m_skill;
}
set
{
if( m_skill != value )
{
m_skill = value;
}
}
}

private double m_skill;

#endregion

#endregion

#region Constructors

public Person()
{
}

public Person( string name, int age, double skill )
{
this.Name = name;
this.Age = age;
this.Skill = skill;
}

#endregion
}

public class Persons
{
ObservableCollection _personList = new ObservableCollection();

#region Properties

public ObservableCollection PersonList
{
get
{
return _personList;
}
}

#endregion

#region Constructors

public Persons()
{
_personList.Add( new Person( "Mary", 30, 10 ) );
_personList.Add( new Person( "Brad", 25, 9 ) );
_personList.Add( new Person( "Anne", 27, 10 ) );
_personList.Add( new Person( "Eric", 22, 5) );
_personList.Add( new Person( "Lisa", 28, 8 ) );
_personList.Add( new Person( "Carl", 35, 12 ) );
}

#endregion
}`

  1. Bind the Series.BindingContext to Page.BindingContext:
    `
    ...
    xctk:Chart.HorizontalAxis
    <xctk:Axis TickLabelType="Text" />
    </xctk:Chart.HorizontalAxis>
    ....
    <xctk:Series BindingContext="{Binding BindingContext, Source={x:Reference MyPage}}"
    DataPointsSource="{Binding Path=Points}">
    xctk:Series.DataPointsSourceBindingInfos
    <xctk:BindingInfos DataPointPropertyName="Text"
    UserObjectPropertyName="X" />
    <xctk:BindingInfos DataPointPropertyName="Y"
    UserObjectPropertyName="Y" />
    </xctk:Series.DataPointsSourceBindingInfos>
    </xctk:Series>

public MainPage()
{
InitializeComponent();
BindingContext = new ViewModel();
}`

Thank you