Question

I have a silverlight application using telerik charts.

In my view I have the chart in xaml. In the code behind of the view I have something like this:

public partial class MyView : UserControl
{
    private MyViewModel viewModel;

    public MyView()
    {
        InitializeComponent();
        CreateChartMappings();  // Creates the SeriesMappings for my chart
        viewModel = new MyViewModel();
        Chart1.ItemsSource = viewModel.MyChartData;

        DataContext = viewModel;
        Resources.Add("ViewModel", viewModel);

    }
}

In my ViewModel I have this:

public class MyViewModel : INotifyPropertyChanged
{
    private ObservableCollection<ChartData> myChartData;
    public ObservableCollection<ChartData> MyChartData
    {
        get { return myChartData; }
        set { myChartData= value; OnPropertyChanged("MyChartData"); }
    }

    public MyViewModel()
    {
        MyWebServiceClient service = MyWebServiceClient.CreateInstance();

        service.GetChartDataCompleted +=  
            new EventHandler<GetChartDataCompletedEventArgs>(GetChartDataCallback); 

        service.GetChartDataAsync();
    }


    private void GetChartDataCallback(object sender, GetChartDataCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            MyChartData = e.Result;
        }
    }
}

I know for sure that GetChartData will return the correctly typed data that can be used for the chart and see that GetChartDataCallback does return results in e.Result, but I don't know how to get that data loaded into my chart.

If I do something like Chart1.ItemsSource = viewModel.MyChartData; after I am sure the service returns data then data loads into the chart fine. For example, if I create a button in my view that calls that line of code it will load the data from the service into the chart.

Also if I replace the asyc calls with a normal method call it will work okay as well, so my problem might have something to do with not handling the asyc call correctly?

Was it helpful?

Solution

There are two potential problems I see with the code you've presented above:

  1. You're not binding the chart's ItemsSource to your view-model object.

  2. There may be cross-thread issues depending on which thread handles the async callback.

When you assign to the MyChartData property in your GetChartDataCallback method, the PropertyChanged event is being fired. But because you haven't bound anything in the view-layer to it, nothing is listening to this event. Your chart will not get any new data.

To use binding, you can replace the line

Chart1.ItemsSource = viewModel.MyChartData;

with

Binding binding = new Binding("MyChartData") { Source = viewModel };
Chart1.SetBinding(RadChart.ItemsSourceProperty, binding);

Alternatively, you could set up the binding in XAML.

As for the cross-thread issues, I don't have any code for an async service such as yours to test against. Instead, I knocked up a simple test application that attempts to update the view-model data in a separate thread. After making up some data, this application tries to assign this data to a view-model property much like yours above, using the line

ChartData = data;

When I ran this application, this line caused an UnauthorizedAccessException, which mentioned an invalid cross-thread access.

I replaced the line above with

Deployment.Current.Dispatcher.BeginInvoke(() => { ChartData = data; });

This change got rid of the exception and allowed me to see the (made-up) data in the chart. (You'll need to add a line using System.Windows; if you don't already have one.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top