Reputation: 840
I'm trying to bind an ObservableCollection
to a <CarouselView>
. Inside the CarouselView
I've a <Label>
and I'm trying to bind it to a public property inside the ObservableCollection
. However, on compile, I'm getting an error:
Error XFC0045 : Binding: Property "CoursesName" not found on StudentPageModel
I've verified that API call in the StudentPageModel
is working as expected on page load (by commenting out the CarouselView) and correct data is available for binding.
public partial class StudentPageModel() : ObservableObject
{
[ObservableProperty]
private string _studentId = string.Empty;
[ObservableProperty]
private StudentModel? _student;
public ObservableCollection<StudentCourses>? CourseCollection { get; set; }
public async Task OnAppearing()
{
Student = await GetStudent("A100");
// Verified that data is getting populated in both Students and CourseCollection
if (Student is { StudentCourses: not null })
{
CourseCollection = new ObservableCollection<StudentCourses>(Students.StudentCourses);
}
}
}
public class StudentModel : ObservableObject
{
public string? StudentId { get; set; }
public string? Name { get; set; }
public string? Major {get; set;}
public double GPA {get; set;}
public ObservableCollection<StudentCourses>? CoursesTaken { get; set; }
}
public class StudentCourses
{
public string? Id { get; set; }
public string? CoursesName { get; set; }
public string? CoursesGrade { get; set; }
public string? CoursesCredit { get; set; }
public string? CoursesSemester { get; set; }
}
public class StudentLoader() : IStudentManager
{
public async Task<StudentModel> GetStudent(string studentId)
{
try
{
var response = await studentAPI.GetStudentAsync(taskId);
List<StudentCourses>? courses = response.Courses?.Select(course => new StudentCourses
{
Id = course.Id,
CoursesName = course.CoursesName,
CoursesGrade = course.CoursesGrade,
CoursesCredit = course.CoursesCredit,
CoursesSemester = course.CoursesSemester
}).ToList();
StudentModel student = new()
{
StudentId = response.StudentId,
Name = response.Name,
Major = response.Major,
GPA = response.GPA
};
if (courses != null)
{
student.Courses = new ObservableCollection<StudentCourses>(courses);
}
return student;
}
}
}
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:StudentManager.ViewModels"
x:Class="StudentManager.Pages.StudentPage"
xmlns:controls="clr-namespace:StudentManager.Controls"
x:DataType="vm:StudentPageModel">
<ContentPage.Content>
<VerticalStackLayout>
<Label Text="{Binding StudentId}"
Margin="10,8,10,8"
/>
<Label Text="{Binding Name}"
Margin="10,8,10,8"
/>
<CarouselView ItemsSource="{Binding CourseCollection}"
CurrentItem="{Binding SelectedCourse}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding CoursesName}"
FontAttributes="Bold"
FontSize="18"
HorizontalOptions="Center"
VerticalOptions="Center" />
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</VerticalStackLayout>
</ContentPage.Content>
</ContentPage>
Upvotes: 0
Views: 77
Reputation: 9721
The binding context inside your CarouselView
is of type StudentCourses
, while your previous statement on ContentPage level x:DataType="vm:StudentPageModel"
(cascading to all it children including CarouselView
) is conflicting with that fact, so in this case you have to specify that your CarouselView
is expecting a StudentCourses
as a binding context type:
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:StudentManager.ViewModels"
x:Class="StudentManager.Pages.StudentPage"
xmlns:controls="clr-namespace:StudentManager.Controls"
x:DataType="vm:StudentPageModel">
...
<CarouselView x:DataType="vm:StudentCourses"
ItemsSource="{Binding CourseCollection}"
CurrentItem="{Binding SelectedCourse}">
...
Upvotes: 1