Issue
One of the properties of my model that I use in a CollectionView
in my .NET MAUI app is a class. It looks like this:
public MyModel
{
public string Name { get; set; }
public Vehicle Car { get; set; } = new Vehicle();
}
My view model looks like this:
public class MyViewModel : BaseViewModel
{
ObservableCollection<MyModel> data = new ObservableCollection<MyModel>();
public ObservableCollection<MyModel> Data
{
get => data;
set
{
if(data == value)
return;
data = value;
OnPropertyChanged();
}
}
}
In my collection view, when I try to access one of the properties of the Car
property which is a Vehicle
object, I get an error that tells me that the property is not found.
<CollectionView
Source={Binding Data}>
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label
Text={Binding Car.Make} />
</StackLayout>
<DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Any idea what could be causing this?
Solution
Based on your code,I created a demo, and it works properly on my side.
You can refer to the following code:
MyViewModel.cs
public class MyViewModel: INotifyPropertyChanged
{
ObservableCollection<MyModel> data = new ObservableCollection<MyModel>();
public ObservableCollection<MyModel> Data
{
get => data;
set
{
if (data == value)
return;
data = value;
OnPropertyChanged();
}
}
public MyViewModel() {
Data = new ObservableCollection<MyModel>();
Data.Add(new MyModel { Name ="model_1", Car= new Vehicle {Make="Make1" } });
Data.Add(new MyModel { Name = "model_2", Car = new Vehicle { Make = "Make2" } });
Data.Add(new MyModel { Name = "model_3", Car = new Vehicle { Make = "Make3" } });
Data.Add(new MyModel { Name = "model_4", Car = new Vehicle { Make = "Make4" } });
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Vehicle.cs
public class Vehicle
{
public string Make { get; set; }
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiCollectionApp.MainPage"
xmlns:local="clr-namespace:MauiCollectionApp"
>
<ContentPage.BindingContext>
<local:MyViewModel></local:MyViewModel>
</ContentPage.BindingContext>
<CollectionView ItemsSource="{ Binding Data}">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding Car.Make}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Update:
I tested your demo, there are some problems with your code.
1.define Drivers
as follows:
public ObservableCollection<Driver> Drivers { get; set; } = new ObservableCollection<Driver>();
Not:
public ObservableCollection<Driver> Drivers = new();
2.we should initialize the data in the constructor of MainPageViewModel
,so we can define MainPageViewModel.cs
as follows:
public class MainPageViewModel : ObservableObject
{
//public ObservableCollection<Driver> Drivers = new();
public ObservableCollection<Driver> Drivers { get; set; } = new ObservableCollection<Driver>();
public MainPageViewModel() {
Init();
}
public void Init()
{
var car = new Vehicle
{
Make = "Subaru",
Model = "Outback",
Year = 2019
};
var driver = new Driver
{
Name = "John Smith",
Car = car
};
Drivers.Add(driver);
car = new Vehicle
{
Make = "Infiniti",
Model = "Q80",
Year = 2014
};
driver = new Driver
{
Name = "John Doe",
Car = car
};
Drivers.Add(driver);
car = new Vehicle
{
Make = "BMW",
Model = "535i",
Year = 2011
};
driver = new Driver
{
Name = "John Doe",
Car = car
};
Drivers.Add(driver);
}
}
At the same time, remove code _vm.Init();
in method OnAppearing()
:
protected override void OnAppearing()
{
base.OnAppearing();
//_vm.Init();
}
3.add x:DataType
in theVerticalStackLayout
of MainPage.xaml.cs
<CollectionView.ItemTemplate>
<DataTemplate >
<VerticalStackLayout x:DataType="local:Driver">
<Label
Text="{Binding Name}"
TextColor="Black"/>
<Label
Text="{Binding Car.Make}"
TextColor="Black"/>
</VerticalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
Besides,add following code on the root of MainPage.xaml
:
xmlns:local="clr-namespace:MauiApp1"
Answered By - Jessie Zhang -MSFT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.