[英]Wpf MVVM - Binding not applied in ViewModel before View is showing (Async / await)
当我尝试在ViewModel中绑定ObservableCollection时,出现一个小错误。 问题是它连接到Web api来获取列表,但是由于某种原因,它不够快。
我认为这与async / await有关,在这里它不等待列表在加载视图之前获取其数据。
码:
public ObservableCollection<AvailableRoomModel> AvailableRooms { get; set; }
public ObservableCollection<AvailableRoomModel> List { get; set; }
AvailableRooms是正确的列表,该列表仅用于测试。
public RoomsViewModel(IGetAvailableRoomsService getAvailableRoomsService)
{
//Injection
_getAvailableRoomsService = getAvailableRoomsService;
//Initialize
AvailableRooms = new ObservableCollection<AvailableRoomModel>();
//Get all rooms
GetAvailableRooms();
List = new ObservableCollection<AvailableRoomModel>();
List.Add(new AvailableRoomModel { Id = 1, RoomNumber = "101", Occupied = true });
List.Add(new AvailableRoomModel { Id = 2, RoomNumber = "102", Occupied = true });
List.Add(new AvailableRoomModel { Id = 3, RoomNumber = "103", Occupied = true });
}
public async void GetAvailableRooms()
{
try
{
AvailableRooms = await _getAvailableRoomsService.getRooms();
}
catch (Exception e)
{
//TODO
}
}
已经测试过,如果我将我的ItemsControl绑定到名称= List的列表,则它可以工作(足够快),但是在绑定到AvailableRooms时它不起作用。
我真的不希望在可以单击的视图中使用searchCommand,只希望在显示视图之前填充列表。
有任何想法吗?
问题是async void
。 如果要等待方法,则其返回类型必须为Task
或Task<T>
。
public async Task<IEnumerable<AvailableRoomModel>> GetAvailableRooms()
{
try
{
return await _getAvailableRoomsService.getRooms();
}
catch (Exception e)
{
//TODO
}
}
在ctor中,您无法等待此方法,因此可以像这样简单地调用此方法:
public RoomsViewModel(IGetAvailableRoomsService getAvailableRoomsService)
{
//Injection
_getAvailableRoomsService = getAvailableRoomsService;
//Get all rooms
AvailableRooms =
new ObservableCollection<AvailableRoomModel>(
GetAvailableRooms().GetAwaiter().GetResult()
);
// ...
}
更新:
您还应该在视图模型中实现System.ComponentModel.INotifyPropertyChanged
接口,并且必须使用完整属性才能引发PropertyChanged
事件。 ObservableCollection<T>
本身实现此接口,但是设置属性不会引发此事件,除非我们引发它。
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class RoomsViewModel : INotifyPropertyChanged
{
/* constructor goes here from previous code block */
private ObservableCollection<AvailableRoomModel> availableRooms;
public ObservableCollection<AvailableRoomModel> AvailableRooms
{
get { return availableRooms; }
set { availableRooms = value; OnPropertyChanged(); }
}
private ObservableCollection<AvailableRoomModel> list;
public ObservableCollection<AvailableRoomModel> List
{
get { return list; }
set { list = value; OnPropertyChanged(); }
}
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.