Di seguito è riportata un'implementazione di esempio che utilizza Metro API e associazione dati (utilizzando MVVM) per popolare l'elenco di cartelle in un elenco a discesa.Assegnazione di un risultato asincrono a una proprietà di associazione dati
Il costruttore del modello View utilizza il metodo SetFolders (private async), che chiama un metodo attendibile fileService.GetFoldersAsync() per ottenere l'elenco delle cartelle. L'elenco delle cartelle viene quindi assegnato alla proprietà denominata "Lista cartelle". XAML utilizza questa proprietà per compilare un elenco a discesa utilizzando l'associazione dati.
Mi chiedo se esiste un modo migliore per impostare la proprietà FoldersList senza doverlo impostare nel costruttore come di seguito. Preferisco chiamare il metodo GetFilesAsync e impostare il valore della proprietà FilesList, quando si verifica l'associazione dati effettiva (non durante la classe init). Dal momento che le proprietà non supportano i modificatori asincroni/attendi (per quanto ne so) sto faticando a implementare una soluzione adeguata. Qualche idea molto apprezzata.
Il codice è di seguito.
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 e l'attuazione
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();
}
}
Vedo un problema con questa risposta. Il getter della proprietà Folders non attende LoadData che è buono come dovrebbe bloccare. Ma in LoadData è attesa una funzione in modo che il controllo sia restituito al chiamante/alla proprietà. Per me ciò implica che le _folders non sono necessariamente inizializzate e quindi la proprietà Folders può restituire anche null. – buckley
Sì, il controllo verrà restituito al getter. Ma non è un problema, poiché la proprietà IsLoading verrà impostata su true, segnalando che il caricamento è in corso. Quando l'attività fileService.GetFolderAsync() completa, il flusso del metodo LoadData continuerà come previsto. È vero che la proprietà Folders restituirà null alla fine della chiamata. Ma non appena l'attività GetFolderAsync() completa, verrà generato un evento PropertyChanged. – Eilistraee
In effetti, è vero che la proprietà Folders può restituire true. Funziona come previsto: non si desidera bloccare la chiamata, pertanto l'inizializzazione Lazy dei dati non può avvenire in modo sincrono. Se è necessario attendere LoadData, renderlo pubblico e attendere direttamente prima di chiamare le cartelle. Altrimenti, lascia che il Databinding sia aggiornato non appena i Dati sono disponibili, o faccia affidamento su PropertyChanged. – Eilistraee