C# 从属性设置器加载异步数据

C# 从属性设置器加载异步数据,c#,xaml,uwp,C#,Xaml,Uwp,我不确定在绑定属性更改时加载异步数据的最佳方法是什么 我有一个列表视图,当选择一个项目时,我会显示带有详细数据的新内容。详细信息项是从异步方法获得的 数据方法: private async void ShowDetailAsync() { if (SelectedItem?.Id != null) { detailViewModel.Item = await storage.GetDetailItemAsync(SelectedItem.Id); } else {

我不确定在绑定属性更改时加载异步数据的最佳方法是什么

我有一个列表视图,当选择一个项目时,我会显示带有详细数据的新内容。详细信息项是从异步方法获得的

数据方法:

private async void ShowDetailAsync()
{
  if (SelectedItem?.Id != null)
  {
    detailViewModel.Item = await storage.GetDetailItemAsync(SelectedItem.Id);
  }
  else
  {
    detailViewModel.Item = null;
  }
}    
ViewModel属性:

public GearItemListViewModel SelectedItem 
{
  get => selectedItem; 
  set { this.SetValue(ref selectedItem, value); ShowDetailAsync(); } 
}
现在它可以作为fire-and-forget-async方法使用,但是当用户快速浏览ListView中的记录时(第一次单击比另一次单击要花费更长的时间来加载记录),如何才能最好地加载它而不出现视图和数据失步的风险呢

或者有没有其他方法可以在属性设置器中不进行异步调用的情况下切换和加载详细信息项?

我喜欢使用我的示例中描述的“异步属性”方法

在这种情况下,您的
detailViewModel.Item
属性的类型将从
TItem
更改为,并且您的
showdailasync
将变为:

private void ShowDetail()
{
  if (SelectedItem?.Id != null)
  {
    detailViewModel.Item = NotifyTask.Create(storage.GetDetailItemAsync(SelectedItem.Id);
  }
  else
  {
    detailViewModel.Item = null;
  }
}
请注意,该方法是同步的。它正在同步启动异步操作


通过此更改,您的数据绑定将需要更新为引用
项。结果
,而不是
。然后,如果要显示微调器/加载指示器,则可以将数据绑定到其他属性,例如
Item.IsNotCompleted
,以及
Item.IsFaulted
以通知用户错误(使用以前的
async void
方法,任何错误都将直接在UI线程上引发)。

您可以查看并查看他的。谢谢。如何分配空的viewmodel(不是来自异步服务方法)?这样行吗?detailViewModel.Item=新建NotifyTaskCompletion(Task.Factory.StartNew(()=>new GearItemDetailViewModel());或者更好的任务。FromResult(新的GearItemDetailViewModel());然后您应该使用
FromResult
。但是,这样做很奇怪。有人用{x:Bind}试过吗?当我使用静态双向绑定时,当离开目标文本框并更新源时,我会得到null引用异常。该项被分配了新的NotifyTask,因此结果为null,在该绑定之后,系统将尝试更新源(ViewModel.Item.Result…)。动态绑定工作正常。我没有用
{x:Bind}
尝试过它。如果在操作进行过程中确实需要“存根”值,则可以传递
TItem
作为
NotifyTask.Create
的第二个参数。尽管在我看来,如果这些控件正在更改,最好禁用它们。禁用这些控件没有帮助。并不是用户在切换选定项时单击或编辑文本框。我只是将光标放在文本框中,然后在另一个项目的列表中单击,它崩溃了,因为文本框失去了焦点,并试图更新源,其中有新的项目实例,结果还不可用。问题在于textbox焦点丢失和listview项选择更改事件的顺序。目前我没有解决这个问题的方法(除了使用动态绑定)。