Xamarin.Forms MVVM Как загрузить привязываемый Picker с данными из асинхронного процесса во ViewModel? - PullRequest
0 голосов
/ 06 февраля 2019

В моей ViewModel я хочу загрузить данные RegionName источника выбора из таблицы регионов Azure.Я извлекаю данные из таблицы в асинхронном методе, но средство выбора отображает пустой список даже после изменения или сбоя ObservableCollection или List.

При использовании PropertyChanged в самом списке ListRegion происходит сбой приложения.

В моих моделях:

 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 голосов
/ 06 февраля 2019

вы, кажется, делаете много ненужного создания и назначения различных списков данных.Вы должны иметь возможность создать свою 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();
}
...