У меня проблема с привязкой данных к средству выбора в 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 происходит из-за этого позднего связывания. Тем не менее, я не могу понять, как это исправить. Любая помощь приветствуется.