Xamarin.Forms MVVM如何在ViewModel中使用异步过程中的数据加载可绑定Picker?

时间:2019-02-06 02:13:07

标签: mvvm xamarin.forms picker

在我的ViewModel中,我想从Azure区域表中加载Picker源RegionName数据。我以异步方法从表中提取数据,但即使ObservableCollection或List发生更改或崩溃后,Picker也会显示一个空列表。

在ListRegion列表本身上使用PropertyChanged时,应用程序崩溃。

在我的模型中:

 public class Region
    {
        public string Id { get; set; }

        public string RegionName { get; set; }
    }

在我的RegisterPage.xaml中:

<Picker SelectedIndex="{Binding RegionsSelectedIndex, Mode=TwoWay}"
                ItemsSource="{Binding Regions}"
                Margin="0,15,0,0"
                Title="Select a region">
</Picker>

在我的RegisterPage.cs中:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class RegisterPage : ContentPage
{
    RegisterViewModel registerVM;

    public RegisterPage ()
    {
        InitializeComponent ();

        registerVM = new RegisterViewModel();
        this.BindingContext = registerVM;   
    }

    protected override void OnAppearing()
    {
        base.OnAppearing();
    }

在我的RegisterPageViewModel中:

public class RegisterViewModel: INotifyPropertyChanged
    {
        ApiServices _apiServices = new ApiServices();


        public RegisterViewModel()
        {      
           initializePickerAsync();
        }


        async private void initializePickerAsync()
        {
            try
            {
                var regionsList = await App.MobileService.GetTable<Models.Region>().ToListAsync();

                List<string> regionsStringList = new List<string>();

                foreach (Models.Region reg in regionsList)
                {
                    regionsStringList.Add(reg.RegionName);
                }

                Regions = regionsStringList;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }

        /*


    private RegisterViewModel (ObservableCollection<Models.Region> regionData)
        {

            ObservableCollection<string> regionDataAsStringList = new ObservableCollection<string>();

            foreach (Models.Region r in regionData)
            {
                regionDataAsStringList.Add(r.RegionName);
            }

            this.Regions = regionDataAsStringList;
        }

        async public static Task<RegisterViewModel> BuildViewModelAsync()
        {
            ObservableCollection<Models.Region> tmpRegionData = new ObservableCollection<Models.Region>(await App.MobileService.GetTable<Models.Region>().ToListAsync());

            return new RegisterViewModel(tmpRegionData);
        }
        */

        int regionsSelectedIndex = 0;

        public int RegionsSelectedIndex
        {
            get
            {
                return regionsSelectedIndex;
            }
            set
            {
                if (regionsSelectedIndex != value)
                {
                    regionsSelectedIndex = value;

                    OnPropertyChanged(nameof(RegionsSelectedIndex));

                    if (regionsSelectedIndex >= 0)
                    {
                        Region = Regions[regionsSelectedIndex];
                    }               
                }
            }
        }

       // public ObservableCollection<Region> Regions {get;set}

        public List<string> Regions
        {
            get
            {
                return Regions;
            }
            set
            {
                if (Regions != value)
                {
                    Regions = value;

                    OnPropertyChanged(nameof(Regions));

                }
            }
        }



        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

您似乎在做很多不必要的创建和分配不同数据列表的工作。您应该能够创建ObservableCollection ONCE,然后将数据添加到其中,就像这样

在您的ViewModel中

ObservableCollection<Region> Regions { get; set; }

public RegisterViewModel()
{      
    Regions = new ObservableCollection<Region>();
}

public async void GetData()
{
    var regionsList = await App.MobileService.GetTable<Models.Region>().ToListAsync();

    foreach (Models.Region reg in regionsList)
    {
        Regions.Add(reg);
    }
}

在您的页面中

protected async override void OnAppearing()
{
    base.OnAppearing();

    await registerVM.GetData();
}