Привязка средства выбора форм Xamarin прерывается при изменении источника элементов - PullRequest
0 голосов
/ 09 мая 2020

У меня проблема с привязкой данных к средству выбора в Xamarin Forms, и, надеюсь, кто-нибудь может мне помочь. У меня есть ContentPage, который содержит сборщик. Источник элементов для этого средства выбора запрашивается асинхронно c из веб-службы. Кроме того, представлению (или, скорее, ViewModel) передается выбранный элемент. По какой-то причине установка itemssource нарушает привязку свойства SelectedItem.

Вот моя ViewModel -

public class ExerciseViewModel:BaseViewModel
    {
        private ApiServices apiService = new ApiServices();
        private Exercise exercise;
        public Exercise Exercise
        {
            get => exercise;
            set
            {
                exercise = value;
                OnPropertyChanged();
            }
        }

        private List<ExerciseCategory> exerciseCategories = new List<ExerciseCategory>();
        public List<ExerciseCategory> ExerciseCategories
        {
            get => exerciseCategories;
            set
            {
                exerciseCategories = value;
                OnPropertyChanged();
            }
        }

        public ExerciseViewModel()
        {
            GetCategoriesCommand.Execute(null);
            Exercise = new Exercise() { Name = "Neue Übung", Category = ExerciseCategories.FirstOrDefault() };
        }

        public ExerciseViewModel(Exercise ex)
        {
            Exercise = ex;
            GetCategoriesCommand.Execute(null);
        }

        public ICommand GetCategoriesCommand
        {
            get
            {
                return new Command(async () =>
                {
                    ExerciseCategories = await apiService.GetExerciseCategories();
                });
            }
        }

        public ICommand AddExerciseCommand
        {
            get
            {
                return new Command(async () =>
                {
                    Exercise.Id = await apiService.AddExercise(Exercise);
                });
            }
        }


    }

Это объект, о котором идет речь - необходимые операторы перегружены, INotifyPropertyChanged реализован в BaseClass -

public class ExerciseCategory:BaseClass
    {
        private string name;
        private int id;

        [Key]
        public int Id
        {
            get => id;
            set
            {
                id = value;
                OnPropertyChanged();
            }
        }

        public string Name
        {
            get => name;
            set
            {
                name = value;
                OnPropertyChanged();
            }
        }

        public override bool Equals(object obj)
        {
            var other = (obj as ExerciseCategory);
            if (other is null)
                return false;
            return this == other;
        }
        public static bool operator !=(ExerciseCategory e1, ExerciseCategory e2)
        {
            return !(e1 == e2);
        }

        public static bool operator ==(ExerciseCategory e1, ExerciseCategory e2)
        {
            if (e1.Id == e2.Id)
                if (e1.Name == e2.Name)
                    return true;

            return false;
        }
    }

Это скрытый код страницы:

[XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class NewExercisePage : ContentPage
    {
        public NewExercisePage(ExerciseViewModel viewModel, bool controlsLocked = false)
        {
            try
            {
                this.BindingContext = viewModel;
                InitializeComponent();


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

        private void UpdateWebView(object sender, TextChangedEventArgs e)
        {
            Uri uriResult;
            bool result = Uri.TryCreate(e.NewTextValue, UriKind.Absolute, out uriResult)
                && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
            if (result)
                exerciseVideoViewer.Source = e.NewTextValue;
        }
    }

Наконец, вот XAML -

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="PerformanceTM.Views.NewExercisePage">
    <ContentPage.Content>
        <StackLayout>
            <WebView x:Name="exerciseVideoViewer" HeightRequest="200" WidthRequest="200"></WebView>
            <Grid x:Name="LayoutGrid">
                <Label Text="Kategorie" Grid.Column="0" Grid.Row="0"/>
                <Picker x:Name="CategoryPicker" ItemsSource="{Binding ExerciseCategories}" ItemDisplayBinding="{Binding Name}" SelectedItem="{Binding Exercise.Category}"  Grid.Column="1" Grid.Row="0"/>
                <Label Text="Name" Grid.Column="0" Grid.Row="1"/>
                    <Entry Text="{Binding Exercise.Name}" Grid.Column="1" Grid.Row="1"/>
                    <Label Text="Video URL" Grid.Column="0" Grid.Row="2"/>
                    <Entry Text="{Binding Exercise.VideoUrl}" Grid.Column="1" Grid.Row="2" TextChanged="UpdateWebView"/>
                    <Label Text="Beschreibung" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3"/>
                    <Editor Text="{Binding Exercise.Description}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="4"/>
                </Grid>
            <Button Text="Speichern" Command="{Binding AddExerciseCommand}"/>
            <Label Text="{Binding Exercise.Category.Name}"/>
        </StackLayout>

    </ContentPage.Content>
</ContentPage>

Когда я выбираю ExerciseCategory из CategoryPicker, привязка работает. Однако ExerciseCategory, которая предоставляется ViewModel через параметр "ex", не приводит к выбору правильной категории в Picker. , Я подозреваю, что это разъединение между Exercise.Category и Picker.SelectedItem происходит из-за этого позднего связывания. Тем не менее, я не могу понять, как это исправить. Любая помощь приветствуется.

...