2013-03-07 36 views
0

我第一次對我的應用程序使用了MVVM模式。我創建了一個視圖類,一個ViewModel類,一個Command類。當我點擊按鈕上的視圖時,我在viewModel中啓動了綁定命令。在這個命令中,我創建了一個HttpWebRequest,從Web服務加載新聞作爲json對象。在'GetNewsResponseCallback'方法中,我將我的數據作爲json流。 seriallisation正常工作。當我在這個方法中調用'PropertyChanged(this,new PropertyChangedEventArgs(「News」))'時,我得到一個COMException。但我需要PropertyChange事件來更新我的視圖中的Listview。我該如何解決這個問題?從我的命令開始服務是正確的嗎?使用MVVM-Pattern開發我很新。在下面我的代碼:從視圖模型(MVVM)中的命令調用HttpWebRequest

<Canvas> 
    <Button Content="Aktualisieren" 
      Canvas.Top="20" 
      Canvas.Left="600" 
      Command="{Binding SynchronizeNewsCommand}"/> 

    <ListView x:Name="viewBox" 
       ItemsSource="{Binding News}" 
       ItemTemplate="{StaticResource newsTemplate}"/> 

</Canvas> 
public class MyCommand<T> : ICommand 
    { 
     readonly Action<T> callback; 


     public MyCommand(Action<T> callback) 
     { 
      this.callback = callback; 
     } 


     public bool CanExecute(object parameter) 
     { 
      return true; 
     } 


     public event EventHandler CanExecuteChanged; 


     public void Execute(object parameter) 
     { 
      if (callback != null) { callback((T)parameter); } 
     } 

    } 



public class NewsViewModel : INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     public ObservableCollection<NewsSerializer> News { get; set; } 

     public MyCommand<object> SynchronizeNewsCommand { get; set; } 


     public NewsViewModel() 
     { 
      SynchronizeNewsCommand = new MyCommand<object>(SynchronizeNews); 
     } 


     private void SynchronizeNews(object obj) 
     { 
      HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Constans.uri); 
      request.ContentType = "application/json; charset=utf-8"; 
      request.Accept = "application/json"; 
      request.Method = "POST"; 
      request.BeginGetRequestStream(new AsyncCallback(GetNewsRequestStreamCallback), request); 
     } 


     private void SynchronizeFinished(object obj) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("News")); 
     } 


     private void GetNewsRequestStreamCallback(IAsyncResult asynchronousResult) 
     { 
      HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 
      request.BeginGetResponse(new AsyncCallback(GetNewsResponseCallback), request); 
     } 


     private void GetNewsResponseCallback(IAsyncResult asynchronousResult) 
     { 
      HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 

      // End the operation 
      HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); 
      Stream streamResponse = response.GetResponseStream(); 

      DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObservableCollection<NewsSerializer>)); 
      News = (ObservableCollection<NewsSerializer>)ser.ReadObject(streamResponse); 

      PropertyChanged(this, new PropertyChangedEventArgs("News")); 
     } 

    } 

回答

1

通常情況下,使用一個ObservableCollection的時候 - 你不必每次都重新創建它。您應該調用Clear()來代替(或刪除已刪除的項目),然後逐個添加新項目。你的看法會的變化自動通知你不會需要調用的PropertyChanged

private void GetNewsResponseCallback(IAsyncResult asynchronousResult) 
    { 
     HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState; 

     // End the operation 
     HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult); 
     Stream streamResponse = response.GetResponseStream(); 

     DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ObservableCollection<NewsSerializer>)); 
     var res = (IList<NewsSerializer>)ser.ReadObject(streamResponse); 

     News.Clear(); 
     foreach(var item in res) 
     { 
      News.Add(item); 
     } 
    } 

在你的情況,你也應該考慮通過實施的AddRange方法擴展的ObservableCollection類。

+0

感謝您的回覆。我的視圖模型位於便攜式類庫中,用於贏取8個應用程序並贏取手機應用程序。我的觀點是贏得8個贏得電話項目。我認爲這是將一個Collection綁定到我的ListView的最好方法。從我的viewmodel我不能從視圖中獲取我的ListContro。 – Matapolo 2013-03-07 12:38:11

+0

你不需要。我的意思是,你不應該重新分配你的新聞屬性。您應該避免創建新的可觀察集合。通過使用News.Clear(),News.Remove(...)和News.Add(...)來重新使用現有的。 – 2013-03-07 12:53:52

+0

但是這種方法不會在我的視圖中更新ListView控件。 – Matapolo 2013-03-07 13:11:46