5

以下は、メトロAPIとデータバインディング(MVVMを使用)を使用してドロップダウンリストのフォルダーのリストにデータを入力するサンプル実装です。

ビューモデルのコンストラクターは、SetFoldersメソッド(プライベート非同期)を使用します。このメソッドは、待機可能なメソッドfileService.GetFoldersAsync()を呼び出してフォルダーのリストを取得します。次に、フォルダリストが「FoldersList」というプロパティに割り当てられます。XAMLはこのプロパティを使用して、データバインディングを使用してドロップダウンリストにデータを入力します。

以下のようにコンストラクターで設定せずにFoldersListプロパティを設定するより良い方法があるのだろうか。実際のデータバインディングが発生したときに(クラスの初期化中ではなく)、GetFilesAsyncメソッドを呼び出してFilesListプロパティ値を設定したいと思います。プロパティは(私が知る限り)async / await修飾子をサポートしていないため、適切なソリューションを実装するのに苦労しています。どんなアイデアでも大歓迎です。

コードは以下のとおりです。

ViewModel

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();
    }
}
4

1 に答える 1

9

私はそれを怠惰なプロパティとして実装し、ObservableCollection<T>ではなく使用しますIEnumerable<T>。私たちはいくつかのプロジェクトでそれを行っており、それはうまく機能しています。このようにして、必要な場合にのみデータをロードすることを保証できます。さらに、プリフェッチする必要がある場合は、コンストラクターまたは他の場所でいつでもloadメソッドを呼び出すことができます。

ちなみに、私は個人的に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 ...)

于 2012-06-24T09:50:41.273 に答える