Как правильно обрабатывать данные, используя асинхронный сервис с диаграммами silverlight и telerik - PullRequest
0 голосов
/ 16 марта 2012

У меня есть приложение silverlight, использующее Telerik Charts.

На мой взгляд, у меня есть диаграмма в xaml. В коде позади представления у меня есть что-то вроде этого:

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);

    }
}

В моей ViewModel у меня есть это:

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;
        }
    }
}

Я точно знаю, что GetChartData вернет правильно введенные данные, которые могут быть использованы для диаграммы, и вижу, что GetChartDataCallback возвращает результаты в e.Result, но я не знаю, как загрузить эти данные в мою диаграмму.

Если я сделаю что-то вроде Chart1.ItemsSource = viewModel.MyChartData; после того, как я уверен, что служба возвращает данные, данные хорошо загружаются в график. Например, если я создаю в своем представлении кнопку, которая вызывает эту строку кода, она загрузит данные из службы в диаграмму.

Также, если я заменю вызовы asyc обычным вызовом метода, он также будет работать нормально, поэтому моя проблема может быть связана с неправильной обработкой вызова asyc?

1 Ответ

2 голосов
/ 16 марта 2012

Есть две потенциальные проблемы, которые я вижу с кодом, который вы представили выше:

  1. Вы не привязывает ItemsSource диаграммы к вашему объекту модели представления.

  2. Возможны проблемы между потоками в зависимости от того, какой поток обрабатывает асинхронный обратный вызов.

Когда вы присваиваете свойству MyChartData в GetChartDataCallbackметод, событие PropertyChanged запускается.Но поскольку вы ничего не привязали к нему на уровне представления, ничто не слушает это событие.Ваша диаграмма не получит никаких новых данных.

Чтобы использовать привязку, вы можете заменить строку

Chart1.ItemsSource = viewModel.MyChartData;

на

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

В качестве альтернативы, вы можете настроить привязку в XAML.

Что касается проблем с несколькими потоками, у меня нет кода для асинхронной службы, такой как ваша, для тестирования.Вместо этого я запустил простое тестовое приложение, которое пытается обновить данные модели представления в отдельном потоке.После создания некоторых данных это приложение пытается присвоить эти данные свойству модели представления, очень похожему на ваше, используя строку

ChartData = data;

Когда я запустил это приложение, эта строка вызвала исключение UnauthorizedAccessException, в котором упоминалосьневерный межпоточный доступ.

Я заменил строку выше на

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

Это изменение избавило от исключения и позволило мне увидеть (готовые) данные на графике.(Вам нужно добавить строку using System.Windows;, если у вас ее еще нет.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...