0

Telerik チャートを使用する Silverlight アプリケーションがあります。

私の見解では、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 呼び出しを正しく処理していないことに問題がある可能性があります。

4

1 に答える 1

2

上記のコードには、次の 2 つの潜在的な問題があります。

  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;(まだ行がない場合は、行を追加する必要があります。)

于 2012-03-15T22:24:04.943 に答える