我正试图解决这个问题。
我正在为另一组数据交换一个集合中的一组数据。我显示数据的UI显示控件加载时的第一个设置,但是当我更改集合内容时不会更改为新的数据集。
我期望NotifyCollectionChanged方法中的CollectionChanged有订阅,但事实并非如此。
StationName在加载时显示在我的UI上,但在重新加载时不会更改。 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 :(得分:0)
ObservableCollection
会自动提升CollectionChanged
,无需自行提升。它也反对自己,而不是你的VM。
事实上,UI没有理由为它注册(因此是空事件处理程序),因为你的VM甚至没有实现INotifyCollectionChanged
(不是你应该的)。
相反,请在您的收藏的NotifyPropertyChanged
函数中调用set
,然后摆脱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
}
ItemsSource
的{{1}} 仍设置为旧集合!您所做的就是重新分配您的本地变量,ListBox
根本不受影响。这就是你通常不直接设置UI属性的原因。相反,您将绑定 ListBox
绑定到VM上的属性,然后仅更改该属性,而不是交换整个对象。
同时,请考虑将ItemsSource
重新分配给新集合。