2015-01-09 98 views
1

我正在繞圈試圖弄清楚這一點。更改集合,CollectionChanged始終爲空

我正在換出另一組數據的集合中的一組數據。顯示數據的我的用戶界面顯示了控件加載的第一組罰款,但在更改集合內容時不會更改爲新的一組數據。

我期待着NotifyCollectionChanged方法中的CollectionChanged有一個訂閱,但它沒有。

StationName在加載時顯示在我的用戶界面上,但在重新加載時不會更改。 StationListOfMovements在加載時在我的UI上顯示,但在重新加載時不會更改。

我可以在代碼中更改現有集合中的單個項目。我在哪裏錯了?

它顯示數據

public partial class CisArrivalsPanel : UserControl 
    { 
     private ApiDataArrivalsDepartures _theArrivalsDepartures; 

     public CisArrivalsPanel() 
     { 
      InitializeComponent(); 

      _theArrivalsDepartures = new ApiDataArrivalsDepartures(); 

      _theArrivalsDepartures = MakeQuery.LiveTrainArrivals("London Kings Cross"); //load the first set of data into the collection 

      this.DataContext = _theArrivalsDepartures; 

      ListBoxArr.ItemsSource = _theArrivalsDepartures.StationMovementList;    
     } 


     //this invokes the data collection reload as a test 
     private void StationHeader_OnPreviewMouseDown(object sender, MouseButtonEventArgs e) 
     { 
      Reload(); 

      Debug.WriteLine(_theArrivalsDepartures.StationName); 
      foreach (var a in _theArrivalsDepartures.StationMovementList) 
      { 
       Debug.WriteLine(a.OriginName); 
       Debug.WriteLine(a.BestArrivalEstimateMins); 
      } 
     } 

     //here I am swapping out the collection contents 
     void Reload() 
     { 
      _theArrivalsDepartures = MakeQuery.LiveTrainArrivals("London Paddington"); //load the second set of data into the collection 

     } 
    } 

收集

public class ApiDataArrivalsDepartures : INotifyPropertyChanged 
    { 
     private string _stationName; 
     [JsonProperty(PropertyName = "station_name")] 
     public string StationName { 
      get 
      { 
       return _stationName; 
      } 
      set 
      { 
       _stationName = value; 
       NotifyPropertyChanged("StationName"); 
      } 
     } 

     private DateTime _requestTime; 
     [JsonProperty(PropertyName = "request_time")] 
     public DateTime RequestTime { 
      get 
      { 
       return _requestTime; 
      } 
      set 
      { 
       _requestTime = value; 
       NotifyPropertyChanged("RequestTime"); 
      } 
     } 

     private string _stationCode; 
     [JsonProperty(PropertyName = "station_code")] 
     public string StationCode { 
      get 
      { 
       return _stationCode; 
      } 
      set 
      { 
       _stationCode = value; 
       NotifyPropertyChanged("StationCode"); 
      } 
     } 

     private ObservableCollection<StationListOfMovements> _stationMovementList; 

     public ObservableCollection<StationListOfMovements> StationMovementList 
     { 
      get 
      { 
       return _stationMovementList; 
      } 
      set 
      { 
       _stationMovementList = value; 
       NotifyCollectionChanged("StationMovementList"); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged(string property) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(property)); 
      } 
     } 

     public event NotifyCollectionChangedEventHandler CollectionChanged; 

     private void NotifyCollectionChanged(string property) 
     { 
      if (CollectionChanged != null) 
      { 
       CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset,property));  
      }    
     } 
    } 


    public class StationListOfMovements : INotifyPropertyChanged 
    { 

     private string _mode; 
     [JsonProperty(PropertyName = "mode")] 
     public string Mode 
     { 
      get 
      { 
       return _mode; 
      } 
      set 
      { 
       _mode = value; 
       NotifyPropertyChanged("Mode"); 
      } 
     } 


     private string _service; 
     [JsonProperty(PropertyName = "service")] 
     public string Service { 
      get 
      { 
       return _service; 
      } 
      set 
      { 
       _service = value; 
       NotifyPropertyChanged("Service"); 
      } 
     } 

     private string _trainUid; 
     [JsonProperty(PropertyName = "train_uid")] 
     public string TrainUid { 
      get 
      { 
       return _trainUid; 
      } 
      set 
      { 
       _trainUid = value; 
       NotifyPropertyChanged("TrainUid"); 
      } 
     } 

     private string _originName; 
     [JsonProperty(PropertyName = "origin_name")] 
     public string OriginName { 
      get 
      { 
       return _originName; 
      } 
      set 
      { 
       _originName = value; 
       NotifyPropertyChanged("OriginName"); 
      } 
     } 

     private string _destinationName; 
     [JsonProperty(PropertyName = "destination_name")] 
     public string DestinationName { 
      get 
      { 
       return _destinationName; 
      } 
      set 
      { 
       _destinationName = value; 
       NotifyPropertyChanged("DestinationName"); 
      } 
     } 

     private string _platform; 
     [JsonProperty(PropertyName = "Platform")] 
     public string Platform { 
      get 
      { 
       return _platform; 
      } 
      set 
      { 
       _platform = value; 
       NotifyPropertyChanged("Platform"); 
      } 
     } 

    //This is a long boring class, snipped until.... 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void NotifyPropertyChanged(string property) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(property)); 
      } 
     } 
    } 

UPDATE1控制:

/// <summary> 
     /// Gets train arrivals for a station 
     /// </summary> 
     /// <param name="station">The station.</param> 
     /// <returns>ApiDataArrivalsDepartures</returns> 
     public static ApiDataArrivalsDepartures LiveTrainArrivals(string station) 
     { 

      string crsCode; 
      OvergroundStations.StationDictionary.TryGetValue(station, out crsCode); 

      //construct url 
      var queryUrl = new Uri(string.Format("{0}{1}{2}{3}",ApiBaseUrl,"train/station/",crsCode,"/live_arrivals")); 

      //get json data from API 
      var jsonString = GetDataFromApi(queryUrl); 

      //convert to root arrival object 
      var arrivals = Deseralise<ApiDataArrivalsDepartures>(jsonString) as ApiDataArrivalsDepartures; 

      //convert arrivals board data 
      if (arrivals != null) 
       arrivals.StationMovementList = Deseralise<ObservableCollection<StationListOfMovements>>(jsonString, "arrivals", "all") as ObservableCollection<StationListOfMovements>; 

      return arrivals; 
     } 

更新2:

static object Deseralise<T>(string jsonString, string token1, string token2) 
     { 
      var deserializeObject = new object(); 

      try 
      { 
       var jsonPass1 = JObject.Parse(jsonString).SelectToken(token1).ToString(); 

       var jsonPass2 = JObject.Parse(jsonPass1).SelectToken(token2).ToString(); 

       deserializeObject = JsonConvert.DeserializeObject<T>(jsonPass2); 
      } 
      catch (Exception ex) { } 

      return deserializeObject; 
     } 

回答

0

ObservableCollection將提高CollectionChanged自動,有無需自己提出。它也在提高它本身,而不是你的虛擬機。

事實上,UI沒有理由註冊它(因此爲空事件處理程序),因爲您的虛擬機甚至沒有實現INotifyCollectionChanged(並非您應該)。

取而代之,在set函數中調用NotifyPropertyChanged爲您的收藏,並擺脫CollectionChanged。還請確保時間您設置變量,您通過屬性而不是字段。通過字段設置將不會運行屬性的set功能,因此NotifyPropertyChanged將不會運行。

更新 雖然我原來的看法仍然是好東西要注意的,我現在看到的實際問題:

//here I am swapping out the collection contents 
    void Reload() 
    { 
     _theArrivalsDepartures = MakeQuery.LiveTrainArrivals("London Paddington"); //load the second set of data into the collection 
    } 

ItemsSourceListBox的是仍然設置爲舊的收藏!您所做的全部重新分配您的本地變量,ListBox根本不受影響。這樣的陷阱是爲什麼你通常不要直接設置UI屬性。相反,你會綁定ItemsSource到虛擬機上的一個屬性,然後只更改該屬性而不是交換出整個對象。

與此同時,考慮將ItemsSource重新分配給新的集合。

+0

我開始感覺到你在跟着我;)做了改變(NotifyPropertyChanged(「StationMovementList」);)我的用戶界面仍然不會改變 – Damo 2015-01-09 23:04:36

+0

@Damo大聲笑,跟着你:沒有。在[tag:C#]和[tag:WPF]之後,是的:)你是否確定要設置* Property *而不是* Field *(幾段代碼設置字段)。除非你修改屬性,否則setter和事件將不會觸發 – BradleyDotNET 2015-01-09 23:06:25

+0

上面的集合代碼幾乎就是它。 (我只是剪掉了一些屬性和字段)除了作爲屬性的一部分,我沒有在其他地方設置字段。 – Damo 2015-01-09 23:14:39