using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Windows.UI.Xaml.Controls; namespace App14 { public class ViewModel : INotifyPropertyChanged { public ViewModel() => LoadFilteredData(string.Empty); private string _filter; public string Filter { get => this._filter; set { this._filter = value; LoadFilteredData(value); } } private ObservableCollection col; public ObservableCollection View { get => col; } DataModel m; private async void LoadFilteredData(string filter) { if (m == null) { m = new DataModel(); m.DataLoaded += M_DataLoaded; col = m.Collection; } await m.HandleDataItems(filter); } private void M_DataLoaded(object sender, EventArgs e) => OnPropertyChanged(nameof(View)); public event PropertyChangedEventHandler PropertyChanged; internal void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); } internal class DataModel { public event EventHandler DataLoaded; SynchronizationContext sc = SynchronizationContext.Current; public ObservableCollection Collection = new ObservableCollection(); string actualFilter; public async Task HandleDataItems(string filter) { actualFilter = filter; Collection.Clear(); for (int i = 1; i < 1000; i++) { // step 1 - Read next data Data d = await SimulateReadData(i); // step 2 - break if old filter if (actualFilter != filter) break; // step 3 - Put read data in observable collection if (string.IsNullOrEmpty(filter) || d.Info.Contains(filter)) Collection.Add(d); // step 4 - continue after writing readed data to observable collection }; // step 5 - Trigger event to signal end of loading sc.Post(new SendOrPostCallback((state) => DataLoaded?.Invoke(this, new EventArgs())), null); } private async Task SimulateReadData(int index) { return await Task.Run(() => { Thread.Sleep(10); // simulate working time return new Data() { Info = $"Row {index}" }; }); } } public class Data { public int ID { get; set; } public string Info { get; set; } } }