0

ObservableCollection、SaloonList を持つ ViewModel があり、データベースからのデータを入力しています。以下のコードは、すべてが ViewModel ファイルにある場合に機能します。

    public MainViewModel()
    {
        PopulateList();
    }

    private void PopulateList()
    {
        WebClient webClient = new WebClient();
        Uri site = new Uri(_URL);
        UriBuilder uriBuilder = new UriBuilder(site);
        uriBuilder.Path += String.Format("{0}", "all");
        webClient.OpenReadCompleted += SaloonsCompleted;
        webClient.OpenReadAsync(uriBuilder.Uri);
    }

    private void SaloonsCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error != null) { return; }

        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DBSaloons));
        DBSaloons jsonResponse = (DBSaloons)ser.ReadObject(e.Result);
        this.SaloonList = jsonResponse.Results;
        e.Result.Close();
    }

ただし、PopulateList メソッドを ViewModel から分離しようとして、以下のコードを使用すると、アクションのリストが読み込まれ、フェッチされたサルーンの数がデバッガー ウィンドウに出力されても、SaloonList は読み込まれません。

   public MainViewModel()
   {      
      Models.Fetcher fetch = new Fetcher();
      fetch.PopulateList(this.SaloonList, onComplete);
   }

   Action<ObservableCollection<Saloon>, OpenReadCompletedEventArgs> onComplete = (ObservableCollection<Saloon> list, OpenReadCompletedEventArgs e) =>
   {
        if (e.Error != null) { Debug.WriteLine("Fetch Error"); return; }
        DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DBSaloons));
        DBSaloons jsonResponse = (DBSaloons)ser.ReadObject(e.Result);
        list = jsonResponse.Results;
        e.Result.Close();
        Debug.WriteLine("Fetched: " + list.Count.ToString() + " saloons");
    };

fetcher クラスのメソッドは次のようになります。

 public void PopulateList(ObservableCollection<Saloon> list, Action<ObservableCollection<Saloon>, OpenReadCompletedEventArgs> onComplete)
    {
        Debug.WriteLine("Fetching...");
        WebClient webClient = new WebClient();
        Uri site = new Uri(_URL);
        UriBuilder uriBuilder = new UriBuilder(site);
        uriBuilder.Path += String.Format("{0}", "all");

        webClient.OpenReadCompleted += (object sender, OpenReadCompletedEventArgs e) => onComplete(list, e);
        webClient.OpenReadAsync(uriBuilder.Uri, list);
    }

私は何を間違っていますか?

編集:

このように解決しましたが、

public void PopulateList(Action<DBSaloons> callback, Action<Exception> exception)
    {
        Debug.WriteLine("Fetching...");
        WebClient webClient = new WebClient();
        Uri site = new Uri(_URL);
        UriBuilder uriBuilder = new UriBuilder(site);
        uriBuilder.Path += String.Format("{0}", "all");

        webClient.OpenReadCompleted += ((sender, e) =>
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DBSaloons));
            DBSaloons jsonResponse = (DBSaloons)ser.ReadObject(e.Result);
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
               if (e.Error == null) callback(jsonResponse);
                else exception(e.Error);
            });
            e.Result.Close();
        }
        );
        webClient.OpenReadAsync(uriBuilder.Uri);
    }

そして、ViewModel で次のようなサルーンのリストを取得します。

       fetch.PopulateList( (list) =>
        {
            Debug.WriteLine("Fetched: " + list.Results.Count.ToString() + " saloons");
            this.SaloonList = list.Results;

        }, (exception) => { });
4

1 に答える 1

0
list = jsonResponse.Results;

リストの参照を上書きしているため、MainViewModel.SaloonListとlistは同じオブジェクトではなくなりました。次のいずれかに置き換えます。

this.SaloonList = jsonResponse.Results;

または、jsonResponse.Resultsの内容を手動でリストにコピーします。

于 2012-05-12T21:06:50.013 に答える