更改集合,集合更改始终为空
本文关键字:集合 | 更新日期: 2023-09-27 18:36:56
我正在兜圈子试图弄清楚这一点。
我正在将集合中的一组数据换成另一组数据。显示数据的 UI 在加载控件时显示第一组精细,但在更改集合内容时不会更改为新数据集。
我希望 NotifyCollectionChanged 方法中的 CollectionChanged 具有订阅,但它没有。
工作站名称在加载时显示在我的 UI 上,但在重新加载时不会更改。工作站移动列表在加载时显示在我的 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));
}
}
}
更新1:
/// <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;
}
ObservableCollection
会自动引发CollectionChanged
,无需自己提高。它还针对自身而不是您的 VM。
事实上,UI 没有理由注册它(因此是空事件处理程序),因为你的 VM 甚至没有实现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
}
ListBox
的ItemsSource
仍然设置为旧收藏!您所做的只是重新分配局部变量,ListBox
完全不受影响。像这样的陷阱是你通常不直接设置 UI 属性的原因。相反,ItemsSource
绑定到 VM 上的属性,然后仅更改该属性,而不是交换整个对象。
同时,请考虑仅将ItemsSource
重新分配给新集合。