Reputation: 3945
I have been looking at many examples of INotifyPropertyChanged().
I went with the following example found on:
https://xamarindev.co.uk/mvvm-and-xamarin-forms/
Ive created a test project with this and it all works fine....using breakpoints I can see for example
public int Age
{
get { return _person.Age; }
set
{
_person.Age = value;
OnPropertyChanged("Age");
OnPropertyChanged("UserInfo");
}
}
is hit when the user changes the age on the app.
Only trouble with this one is that instead of one instance of the Person, I want multiple persons, so I have added in an ObservableCollection to look like:
public class ViewModel1 : BaseModel
{
private ObservableCollection<Person> _Persons;
public ObservableCollection<Person> Persons
{
get { return _Persons; }
set
{
if (_Persons == value) return;
_Persons = value;
}
}
private Person _person;
public ViewModel1()
{
Persons = new ObservableCollection<Person>();
//// set some default here for example
_person = new Person
{
Age = 21,
FirstName = "Steve",
LastName = "Hawkins"
};
Persons.Add(_person);
_person = new Person
{
Age = 19,
FirstName = "JimBob",
LastName = "Jones"
};
Persons.Add(_person);
}
public int Age
{
get { return _person.Age; }
set
{
_person.Age = value;
OnPropertyChanged("Age");
OnPropertyChanged("UserInfo");
}
}
public string FirstName
{
get { return _person.FirstName; }
set
{
_person.FirstName = value;
OnPropertyChanged("FirstName");
OnPropertyChanged("UserInfo");
}
}
public string LastName
{
get { return _person.LastName; }
set
{
_person.LastName = value;
OnPropertyChanged("LastName");
OnPropertyChanged("UserInfo");
}
}
public string UserInfo
{
get
{
// return _person.PersonInfo();
return _Persons[0].PersonInfo();
}
}
}
and then changed the View to display a ListView:
<ContentPage.Content>
<StackLayout>
<ListView x:Name="producttablelist" IsVisible="True" VerticalOptions="FillAndExpand" HasUnevenRows="True" ItemsSource="{Binding Persons}" HeightRequest="1500">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HeightRequest="120" BackgroundColor="Green" HorizontalOptions="StartAndExpand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Editor Grid.Row="1" Grid.Column="1" Text="{Binding FirstName, Mode=TwoWay}" HorizontalOptions="CenterAndExpand" TextColor="Black" />
<Editor Grid.Row="1" Grid.Column="2" Text="{Binding LastName, Mode=TwoWay}" HorizontalOptions="CenterAndExpand" TextColor="Black" />
<Editor Grid.Row="2" Grid.Column="1" Text="{Binding Age, Mode=TwoWay}" HorizontalOptions="CenterAndExpand" TextColor="Black" />
<Label Grid.Row="2" Grid.Column="2" Text="{Binding UserInfo}" HorizontalOptions="StartAndExpand" TextColor="Black" />
</Grid>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
So now, the page loads showing the 2 users, but if the user changes the age on the app...nothing happens..it doesnt post back to Age in the VM...
Could someone please help?
Been looking at other examples found on https://riptutorial.com/xaml/example/28804/binding-to-a-collection-of-objects-with-inotifypropertychanged-and-inotifycollectionchanged
and https://stackoverflow.com/questions/32667408/how-to-implement-inotifypropertychanged-in-xamarin-forms
still cant seem to get it going if I use an ObservableCollection, and as I have other logic to add in when age is changed I would like this done from the VM not from the Person class (which some examples I have found have shown)
TY for any help
Upvotes: 0
Views: 162
Reputation: 101
Maybe try using SetProperty, it inherits from INotifyPropertyChanged i.e write your public property like the code below:
private ObservableCollection<Person> _persons;
public ObservableCollection<Person> Persons
{
get => _persons;
set => SetProperty(ref _persons, value);
}
ps.... your baseModel might need to inherit from INotifyPropertyChanged too if you encounter issues. I also assumed you are using an MVVM framework like PrismMVVM
Upvotes: 1
Reputation: 15806
As the Jason said: the "Age" entry is bound to the Age property of each person object in your data, not to the Age property of the base VM
.
You do not need to write those properties in the ViewModel as they alreay exist in the Person Model.
What you really want to bind is Text="{Binding Person.FirstName, Mode=TwoWay}"
not ViewModel1.FirstName
.
You can write Text="{Binding FirstName, Mode=TwoWay}"
here as data-binding will search the root properties until it find the property FirstName
in Model Person
.
Refer: data-bindings-to-mvvm
Upvotes: 0