我的ViewModel有一个30秒的数据刷新服务委托方法:
public Task OnDataRefreshed(List<MyType> data)
{
this.Data = data;
LongRunningGetDetailsAsync();
return Task.FromResult(0);
}
公共属性Data
在视图中正确显示和刷新。
此处的目的不是等待异步任务(即发即弃)LongRunningGetDetailsAsync()
,因为如果执行同步,它将在显示Data
之前引入显着延迟。我想尽快显示Data
,然后让异步任务按照自己的节奏获取详细信息,然后让视图绑定赶上。
private async Task LongRunningGetDetailsAsync()
{
foreach (MyType dataitem in this.Data)
{
dataitem.Details = await _apiEndpointService.GetDetails(dataitem.Id);
}
}
LongRunningGetDetailsAsync()
是绑定未触发的位置。我在LongRunningGetDetailsAsync
结束时设置了一个断点,观察Data.Details - Data.Details在那里,但它永远不会显示在视图中。
提前感谢您的时间!
修改 改为
public async Task OnDataRefreshed(ObservableCollection<MyType> data)
{
this.Data = data;
await LongRunningGetDetailsAsync();
}
Data
绑定Mvx.MvxListView
。如果列表很长并且项目恰好在视图之外,则一旦滚动到,它将显示更新的模型OK。 “数据”:
public class MyType
{
public string MyProperty { get; set; }
public string Details { get; set; }
}
private ObservableCollection<MyType> _data;
public ObservableCollection<MyType> Data
{
get { return _data; }
set
{
if (SetProperty(ref _data, value))
{
RaisePropertyChanged(() => Data);
}
}
}
查看绑定:
<Mvx.MvxListView
local:MvxBind="ItemsSource Data"
local:MvxItemTemplate="@layout/listitem"
... />
listitem:
<TextView local:MvxBind="Text MyProperty" ...
<TextView local:MvxBind="Text Details" ...
答案 0 :(得分:1)
首先,在您调用函数时使用await
关键字并将您的函数标记为async
。
public async Task OnDataRefreshed(List<MyType> data)
{
this.Data = data;
await LongRunningGetDetailsAsync();
}
据我了解,您希望在获得每个项目后立即在UI中显示项目。如果您的绑定是正确的,上述更改应该满足您的需要。您应该使用ObservableCollection<>
而不是List<>
作为Data
属性。
答案 1 :(得分:0)
由于您要更改Details
属性,因此您需要让视图知道它已更改。您需要使用与Data
属性相同的逻辑:
private string _details;
public string Details
{
get { return _details; }
set
{
if (SetProperty(ref _details, value))
{
RaisePropertyChanged(() => Details);
}
}
}
作为旁注,请尽量避免列表的设置者。在将来,您可能有其他逻辑连接到您的列表,当被覆盖时,只会使事情变得复杂。相反,由于它是ObservableCollection<T>
公开的,因此您可以在getter的值上调用Clear
然后Add
。