分配一个异步结果到数据绑定属性(Assigning an async result to a dat

2019-09-18 10:53发布

下面是使用地铁API和数据绑定(使用MVVM)来填充在下拉列表中的文件夹列表中选择一个样本实现。

视图模型的构造函数使用SetFolders方法(私人异步),它调用的方法awaitable fileService.GetFoldersAsync()来获取文件夹列表。 文件夹列表中,然后被分配到所谓的“FoldersList”的属性。 XAML使用这个属性来使用数据绑定一个下拉列表。

我不知道是否有更好的方法来设置FoldersList属性,而不必设置如下它在构造函数中。 我宁愿叫GetFilesAsync方法,当实际数据绑定(未在类初始化)时设置FilesList属性值。 由于性能不支持异步/等待修饰符(据我所知)我竭力实现一个妥善的解决办法。 任何想法不胜感激。

代码如下。

视图模型

public class FileViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private readonly IFileService fileService;

    public FileDataViewModel(IFileService fileService)
    {
        this.fileService = fileService;
        SetFolders();
    }

    private async void SetFolders ()
    {
        FoldersList = await fileService.GetFoldersAsync();
    }

    private IEnumerable< IStorageFolder > foldersList;
    public IEnumerable<StorageFolder> FoldersList
    {
        get { return foldersList; }
        private set
        {
            foldersList = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("FoldersList"));
            }
        }
    }
}

IFileService和实施

public interface IFileService    {
    Task<IEnumerable<IStorageFolder>> GetFilesAsync();
  }

public class FileService : IFileService
{
    public async Task<IEnumerable<IStorageFolder>> GetFoldersAsync()
    {
        var folder = KnownFolders.DocumentsLibrary;
        return await folder.GetFoldersAsync();
    }
}

Answer 1:

我将实施它作为一个懒惰属性,并使用ObservableCollection<T>而不是IEnumerable<T> 我们在几个项目做它和它运作良好。 这样就可以保证在需要的时候,你只加载数据。 此外,如果需要预取它,你可以随时调用构造函数或其他地方的加载方法。

作为一个方面说明,我personnaly不会直接从我的ViewModels暴露IStorageFolder。

private async Task LoadData()
{
   if(!IsLoading)
  {
    IsLoading = true;
     Folders = new ObservableCollection<Folder>(await fileService.GetFolderAsync());

  }
  IsLoading = false;
}

private ObservableCollection<Folder> _folders;

public  ObservableCollection<Folder> Folders
{
  get
  {
    if(_folders == null)
    {
      LoadData();//Don't await...
    }
    return _folders;

  }
  private set
  {
    SetProperty(ref _folders,value);
  }

}
private bool _isLoading;
public bool IsLoading
{
  get
  {
    return _isLoading;
  }
  private set
  {
    SetProperty(ref _isLoading,value);
  }
}

请注意,您可以使用IsLoading属性显示例如进度环。 可观察到的集合被加载后,你就可以刷新它无需重新创建它。 (_folders.Add,_folders.Remove,_folders.Clear ...)



文章来源: Assigning an async result to a data binding property