更改集合,集合更改始终为空

本文关键字:集合 | 更新日期: 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
    }

ListBoxItemsSource仍然设置为旧收藏!您所做的只是重新分配局部变量,ListBox完全不受影响。像这样的陷阱是你通常直接设置 UI 属性的原因。相反,ItemsSource绑定到 VM 上的属性,然后仅更改该属性,而不是交换整个对象。

同时,请考虑仅将ItemsSource重新分配给新集合。