c# - 在构造函数中运行异步方法会停止 ObservableCollection 显示数据
问题描述
在构造函数中调用异步方法时出现问题。ObservableCollection
即使我在跟踪代码时可以在调试中看到它,它也会停止显示数据。为了解决这个问题,我有一个相同方法的非异步版本,但显然这并不理想。如何让我的异步方法在构造函数中正常工作?
如果我调用this.RefreshCarList("")
构造函数,MainWindowViewModel
那么后续调用this.RefreshCarListAsync("")
(不是从构造函数内部)将工作得非常好,并且数据会显示在屏幕上。如果我只打电话this.RefreshCarListAsync("")
,那么数据永远不会显示。
public class MainWindowViewModel
{
private ObservableCollection<Car> carList;
public ICollectionView CarList { get; private set; }
private DataReceivedHandler dataReceivedHandler = new DataReceivedHandler();
public MainWindowViewModel()
{
//this.RefreshCarList(""); // Gets data on startup
this.RefreshCarListAsync("") // Doesn't show any data
this.CarList = new QueryableCollectionView(this.carList, typeof(Car));
}
public void RefreshCarList(string carBrand)
{
this.carList = this.dataReceivedHandler.GetCarList(carBrand);
}
public async Task RefreshCarListAsync(string carBrand)
{
this.carList = await this.dataReceivedHandler.GetCarListAsync(carBrand);
}
}
视图模型使用从服务获取数据的数据接收器类:
public class DataReceivedHandler
{
private CarDataService dataService = new CarDataService();
private List<Car> carList = new List<Car>();
private ObservableCollection<Car> carOC = new ObservableCollection<Car>();
public ObservableCollection<Car> GetCarList(string carBrand)
{
carListFromService = this.dataService.GetCarList(carBrand);
this.carOC.Clear();
foreach (ICar car in carListFromService)
this.carOC.Add(car);
return (this.carOC);
}
public async Task<ObservableCollection<Car>> GetCarListAsync(string carBrand)
{
carListFromService = await Task.Run(() => this.dataService.GetCarList(carBrand)).ConfigureAwait(false);
this.carOC.Clear();
foreach (ICar car in carListFromService)
this.carOC.Add(car);
return (this.carOC);
}
}
服务:
public class CarDataService
{
private List<Car> CarList = new CarList();
public List<Car> GetCarList(string carBrand)
{
return this.CarList;
}
}
更新:
所以我已经尝试了这个作为建议的答案之一,但是它仍然不起作用:
public async Task Initialise()
{
try
{
await this.CarListAsync("");
this.CarList = new QueryableCollectionView(this.carList, typeof(Car));
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
this.viewModel.Initialise(); // in a different class
解决方案
如果在构造函数返回后动态设置属性,则应在类中实现INotifyPropertyChanged
并引发PropertyChanged
事件MainWindowViewModel
:
public class MainWindowViewModel : INotifyPropertyChanged
{
private ICollectionView carList;
public ICollectionView CarList
{
get { return carList; }
private set { carList = value; NotifyPropertyChanged(); }
}
private DataReceivedHandler dataReceivedHandler = new DataReceivedHandler();
public async Task Initialise()
{
try
{
await this.CarListAsync("");
this.CarList = new QueryableCollectionView(this.carList, typeof(Car));
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
public event PropertyChangedEventHandler PropertyChanged;
// This method is called by the Set accessor of each property.
// The CallerMemberName attribute that is applied to the optional propertyName
// parameter causes the property name of the caller to be substituted as an argument.
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}