This is a migrated thread and some comments may be shown as answers.

Binding doesn't work on view's *initial* load

8 Answers 168 Views
Chart for XAML
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Tim
Top achievements
Rank 1
Tim asked on 15 Aug 2014, 01:25 PM
In summary, not all charts in a view display the bound data the first time the view is loaded, in spite of the fact that the properties to which the charts are bound contain valid data. However, on subsequent visits to that view, all charts display data correctly.

Details: I've got a few charts (1 Cartesian chart with multiple line series and 2 Pie charts) in a view in a Win 8.1 project that uses MVVM Light. I have a method that is called by the View Model's constructor that is responsible for retrieving and manipulating the data into a format conducive for binding to the charts. This method is async and uses the await keyword to retrieve the data from the database and then formats the data inline. Finally, the MVVM properties are bound to the lists of formatted data. Here's an example:
public async void Initialize()
{
    try
    {
        IsBusy = true;
 
        // get trend data for the line series chart
        var salesTrendList = await MyBusinessLogic.GetTrendListAsync();
 
        // transform trend data for chart and bind to MVVM Light property, which raises PropertyChanged event
        SalesTrend = PrepareTrendData(salesTrendList);
 
        // now get data for the Pie charts
        var pieList = await MyBusinessLogic.GetPieDataAsync();
 
        // format data for 1st Pie chart
        var salesPYTD = new List<ProdCatSalesComp>();
        var totSalesPYTD = pieList.Where(p => p.Period == (DateTime.Today.Year - 1)).Sum(p => p.SalesAmt);
        foreach (var itm in pieList.Where(p => p.Period == (DateTime.Today.Year - 1)))
        {
            salesPYTD.Add(new ProdCatSalesComp(itm.Category, itm.SalesAmt, (itm.SalesAmt / totSalesPYTD)));
        }
 
        // now bind data to MVVM property for 1st Pie chart, which raises PropertyChanged event
        ProductCategorySalesPYTD = salesPYTD;
 
 
        // format data for 2nd Pie chart
        var salesCYTD = new List<ProdCatSalesComp>();
        ... process data ...
        // now bind data to MVVM property for 2nd Pie chart, which raises PropertyChanged event
        ProductCategorySalesCYTD = salesCYTD
 
    }
    catch (Exception ex)
    {
        ...
    }
    finally
    {
        IsBusy = false;
    }
}

Generally, only one or two of the three charts display their data on the view's initial load. It almost seems as if the view renders the empty charts before data gets applied (which is okay), but then when the data is ready and is bound to the binding properties of the charts, the UI binding doesn't take effect. Here's a snippet of the XAML for one of the Pie charts referenced above in the code block:
<StackPanel Orientation="Vertical">
    <TextBlock Text="Sales by Category - Prior YTD"
               Style="{StaticResource TitleTextBlockStyle}"/>
     
    <telerik:RadPieChart x:Name="CatCompPriorYTD"
                         Width="150" Height="150"
                         Margin="0,30,0,0"
                         ClipToBounds="False"
                         Palette="{StaticResource CustomPalette}" >
         
        <telerik:PieSeries ItemsSource="{Binding ProductCategorySalesPYTD"
                            ShowLabels="True">
            <telerik:PieSeries.ValueBinding>
                <telerik:PropertyNameDataPointBinding PropertyName="Percentage"/>
            </telerik:PieSeries.ValueBinding>
            <telerik:PieSeries.LegendTitleBinding>
                <telerik:PropertyNameDataPointBinding PropertyName="Category"/>
            </telerik:PieSeries.LegendTitleBinding>
        </telerik:PieSeries>
         
    </telerik:RadPieChart>
</StackPanel>

To reiterate - when I then navigate away from this view and then go back to it, everything displays properly. Perhaps this is because the VM and data are already loaded and available. But that shouldn't matter. It shouldn't matter whether it takes 2 seconds or 1 minute to pull and format data...once I bind the data to the charts, they should update on the UI. Correct? Any ideas? Thanks.

8 Answers, 1 is accepted

Sort by
0
Tim
Top achievements
Rank 1
answered on 16 Aug 2014, 08:07 PM
Update: I'm still having this problem, and it is random. What I tried was to put my charts into a user control, thinking that perhaps the original location of the charts (directly in a HubSection on the app's main page) was causing some sort of issue. The consistency of the data appearing in the charts has improved some since I moved it to a user control, but nevertheless it is still unreliable.
0
Tim
Top achievements
Rank 1
answered on 16 Aug 2014, 08:45 PM
One more important update: the problem isn't just that the charts are sometimes empty even though their ItemsSource properties contain data. More precisely, the problem is that the charts don't update period when the view is refreshed. Case in point, look at the attached image. The pie chart on the right (Current YTD) shows data, but its ItemSource is actually empty! You can tell by looking at the number circled in red. I put a TextBlock there and bound it to the right pie chart's ItemSource and did a count. As in:

<TextBlock Text="{Binding SalesCYTD.Count}"/>

Note that the previous display of this particular view was for another customer that actually had data in the right pie chart, but that previous customer's data is still being displayed even though a new customer was selected in the view. The TextBlock I included proves that the new customer's right pie chart should be empty because there are zero items in the ItemsSource property. But as you can see, that pie chart still shows data that no longer exists and isn't relevant in the refreshed view.
0
Tim
Top achievements
Rank 1
answered on 17 Aug 2014, 12:44 AM
Yet another example and another way of trying to get this to work. I placed a button on the UI next to one of the charts and have the button's click event in code-behind so that I can force a bind to occur manually. (Note that I changed the chart's series' binding to UpdateSourceTrigger=Explicit to test this.) Here's the code in the button's click-event:

BindingExpression be = CatCompPriorYTD.Series[0].GetBindingExpression(Telerik.UI.Xaml.Controls.Chart.PieSeries.ItemsSourceProperty);
be.UpdateSource();

And you can see from the screen shot at runtime what type of data exists in the chart's series' ItemsSource property (named ProductCategorySalesPYTD).

Yet nothing happens even when trying to bind here. Quite frustrating. I hope this is something that I'm doing wrong. Thanks for your help.




0
Ivaylo Gergov
Telerik team
answered on 20 Aug 2014, 01:13 PM
Hello Tim,

I tried to reproduce this issue but with no avail. In order to further investigate this case, I suggest the following: I have attached a sample project that simply navigates to another view that contains chart. This view has no initial data loaded. After 10 seconds, using a timer, I load the data and the chart responds correctly. Could you please take a look and try to modify the project in order to reproduce the erroneous behavior?

I am looking forward to your reply.
 
Regards,
Ivaylo Gergov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Tim
Top achievements
Rank 1
answered on 21 Aug 2014, 12:00 PM
Ivaylo, I've tried many things, including using a Delay similarly to what you did. In that case, I observed that all other controls correctly load after X seconds, but not the charts. However, after a lot of experimenting, I discovered that if I instantiate my VMs ahead of time (before the views containing the charts are created) that seems to resolve the issue.

Note that I'm not actually loading all the data ahead of time...that still happens when the View is created and triggers a data load method within the VM. But the process of instantiating the VM ahead of time apparently provides the necessary time for the VM to register MVVM Light messages so that the data load processes can be trigger immediately when those messages are received.

My guess is that this is some strange combination of using MVVM Light messages and chart binding. It doesn't make complete sense to me. I may circle back to you on this issue because I'm not thrilled about the method I'm taking to mitigate the problem.
0
Ivaylo Gergov
Telerik team
answered on 26 Aug 2014, 08:24 AM
Hi Tim,

We will continue investigating this problem. In case the workaround which you have found does not suit your needs and meanwhile we do not manage to reproduce the issue, the next step would be to schedule a remote session.


Regards,
Ivaylo Gergov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
KI performance
Top achievements
Rank 1
answered on 17 Oct 2014, 09:41 AM
We are using Telerik charts in combination with MVVM light and experiencing similar problems. Loading the view model beforehand, as Tim suggested, didn't work though. Strange thing is that it only occurs on two particular charts and, as Tim said, only one the page's inital load. 
0
Ivaylo Gergov
Telerik team
answered on 22 Oct 2014, 10:32 AM
Hi,

Again, to further investigate the issue we will need a sample app that reproduces it.

Regards,
Ivaylo Gergov
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
Chart for XAML
Asked by
Tim
Top achievements
Rank 1
Answers by
Tim
Top achievements
Rank 1
Ivaylo Gergov
Telerik team
KI performance
Top achievements
Rank 1
Share this question
or