5

नीचे एक नमूना कार्यान्वयन है जो ड्रॉप डाउन सूची में फ़ोल्डर की सूची पॉप्युलेट करने के लिए मेट्रो एपीआई और डेटा बाइंडिंग (एमवीवीएम का उपयोग करके) का उपयोग करता है।डेटा बाध्यकारी प्रॉपर्टी पर एक async परिणाम असाइन करना

व्यू मॉडल का कन्स्ट्रक्टर सेटफोल्डर्स विधि (निजी async) का उपयोग करता है, जो फ़ोल्डर की सूची प्राप्त करने के लिए एक प्रतीक्षा करने योग्य विधि फ़ाइल सेवा.गेटफोल्डर्सएसिंक() को कॉल करता है। फ़ोल्डरों की सूची को "फ़ोल्डर्सलिस्ट" नामक संपत्ति को सौंपा जाता है। XAML डेटा बाध्यकारी का उपयोग करके ड्रॉप डाउन सूची को पॉप्युलेट करने के लिए इस प्रॉपर्टी का उपयोग करता है।

मुझे आश्चर्य है कि फ़ोल्डर्सलिस्ट संपत्ति को नीचे कन्स्ट्रक्टर में सेट किए बिना सेट करने का एक बेहतर तरीका है। मैं GetFilesAsync विधि को कॉल करना पसंद करता हूं और जब वास्तविक डेटा बाध्यकारी होता है (कक्षा init के दौरान नहीं), FilesList गुण मान सेट करें। चूंकि गुण एसिंक/प्रतीक्षा मॉडिफायर्स का समर्थन नहीं करते हैं (जहां तक ​​मुझे पता है) मैं एक उचित समाधान को लागू करने के लिए संघर्ष कर रहा हूं। किसी भी विचार की सराहना की।

कोड नीचे है।

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

उत्तर

6

मैं एक आलसी संपत्ति के रूप में यह लागू करने और IEnumerable<T> बजाय ObservableCollection<T> का प्रयोग करेंगे। हम इसे कई परियोजनाओं में कर रहे हैं और यह अच्छी तरह से काम करता है। इस तरह आप गारंटी दे सकते हैं कि आवश्यकता होने पर आप केवल डेटा लोड कर रहे हैं। इसके अलावा, अगर आपको इसे प्रीफेच करने की ज़रूरत है, तो आप हमेशा कन्स्ट्रक्टर या अन्य जगहों में लोड विधि को कॉल कर सकते हैं।

एक साइड नोट के रूप में, मैं व्यक्तिगत रूप से अपने 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 ...)

+0

मुझे इस उत्तर में कोई समस्या दिखाई देती है। संपत्ति का गेटर्स फ़ोल्डर्स लोडडेटा का इंतजार नहीं करता है जो इसे ब्लॉक करना चाहिए। लेकिन लोडडाटा में एक समारोह का इंतजार है इसलिए नियंत्रण कॉलर/संपत्ति को वापस दे रहा है। मेरे लिए यह तात्पर्य है कि _ फ़ोल्डर्स जरूरी नहीं है और इस प्रकार फ़ोल्डर्स संपत्ति भी शून्य हो सकती है। – buckley

+0

हां, नियंत्रण गेटटर को वापस दिया जाएगा। लेकिन यह कोई मुद्दा नहीं है, क्योंकि IsLoading प्रॉपर्टी को सत्य पर सेट किया जाएगा, यह संकेत है कि लोडिंग प्रगति पर है। जब fileService.GetFolderAsync() कार्य पूरा हो जाता है, तो लोडडेटा विधि का प्रवाह अपेक्षित के रूप में जारी रहेगा। यह सच है कि फ़ोल्डर्स संपत्ति कॉल के अंत में शून्य हो जाएगी। लेकिन जैसे ही GetFolderAsync() कार्य पूरा हो जाता है, एक PropertyChanged ईवेंट उठाया जाएगा। – Eilistraee

+0

वास्तव में, यह सच है कि फ़ोल्डर्स संपत्ति सच हो सकती है। यह उम्मीद के अनुसार काम करता है: आप कॉल को अवरुद्ध नहीं करना चाहते हैं, इसलिए डेटा का आलसी प्रारंभिक रूप से सिंक्रनाइज़ नहीं हो सकता है। यदि आपको लोडडेटा का इंतजार करना है, तो इसे सार्वजनिक बनाएं और फ़ोल्डर को कॉल करने से पहले इसे सीधे प्रतीक्षा करें। अन्यथा, डेटा उपलब्ध होने पर डाटाबेसिंग को अद्यतन होने दें, या PropertyChanged पर भरोसा करें। – Eilistraee

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^