Poniżej znajduje się przykładowa implementacja, która korzysta z interfejsu API Metro i powiązania danych (przy użyciu MVVM) w celu zapełnienia listy folderów z rozwijanej listy.Przypisywanie wyniku asynchronicznego do właściwości powiązania danych
Konstruktor modelu View korzysta z metody SetFolders (asynchroniczny prywatny), która wywołuje godną zaufania metodę fileService.GetFoldersAsync() w celu pobrania listy folderów. Lista folderów zostanie następnie przypisana do właściwości o nazwie "FoldersList". XAML używa tej właściwości do wypełnienia listy rozwijanej przy użyciu powiązania danych.
Zastanawiam się, czy istnieje lepszy sposób ustawiania właściwości FoldersList bez konieczności ustawiania go w konstruktorze, jak poniżej. Wolałbym wywołać metodę GetFilesAsync i ustawić wartość właściwości FilesList, gdy nastąpi faktyczne powiązanie danych (nie podczas init klasy). Ponieważ właściwości nie obsługują modyfikatorów async/await (o ile mi wiadomo) staram się zaimplementować właściwe rozwiązanie. Wszelkie pomysły bardzo doceniane.
Kod znajduje się poniżej.
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 i realizacja
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();
}
}
Widzę problem z tą odpowiedzią. Zbiór właściwości Folders nie czeka na LoadData, która jest dobra, ponieważ powinna blokować. Ale w LoadData oczekuje się funkcji, więc kontrola jest zwracana do wywołującego/właściwości. Dla mnie oznacza to, że _foldery niekoniecznie są inicjowane, a zatem właściwość Folders może również zwrócić wartość null. – buckley
Tak, kontrola zostanie zwrócona do gettera. Ale to nie problem, ponieważ właściwość IsLoading zostanie ustawiona na wartość true, sygnalizując, że ładowanie jest w toku. Po zakończeniu zadania fileService.GetFolderAsync() przepływ metody LoadData będzie kontynuowany zgodnie z oczekiwaniami. To prawda, że właściwość Folders zwróci wartość null na końcu połączenia. Ale zaraz po zakończeniu zadania GetFolderAsync() zostanie wygenerowane zdarzenie PropertyChanged. – Eilistraee
W rzeczywistości prawdą jest, że właściwość Folders może zwracać wartość true. Działa zgodnie z oczekiwaniami: Nie chcesz blokować połączenia, dlatego inicjalizacja Lazy danych nie może odbywać się synchronicznie. Jeśli musisz poczekać na LoadData, upublicznij go i poczekaj na niego bezpośrednio przed wywołaniem Folderów. W przeciwnym razie należy zaktualizować Databinding, gdy tylko dane będą dostępne, lub polegać na PropertyChanged. – Eilistraee