I have the following CollectionView
-
<CollectionView x:Name="PCollection" ItemsSource="{Binding P.data}" Margin="0,10,2,10">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Image Source="p" HeightRequest="60" WidthRequest="60" />
<StackLayout Orientation="Vertical" >
<Label Text="{Binding id}" VerticalOptions="Center" IsVisible="False"/>
<StackLayout Orientation="Horizontal" >+
<Switch IsToggled="{Binding IsOwned, Mode=TwoWay}" HorizontalOptions="Start" Toggled="Switch_Toggled_Place" />
</StackLayout>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
With my code behind -
bool _isOwned;
public bool IsOwned
{
get
{
return _isOwned;
}
set
{
_isOwned = value;
}
}
private void Switch_Toggled_Place(object sender, ToggledEventArgs e)
{
}
My issue is that when I toggle a switch in the collection, everything works as expected and I step into Switch_Toggled_Place
. However say there are 20 items in the collection, when I scroll up and the toggled switch goes out of view, for some reason it fires the Switch_Toggled_Place
again and unchecks my switch!
I have tried removing the Mode=TwoWay
from the binding to no effect. I also tried to establish if the toggle event was happening from a user input or from the code itself firing but again to no effect. How can I resolve this I am sure it is straightforward.
You need to implement the interface INotifyPropertyChanged
public partial class MyModel: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
bool _isOwned;
public bool IsOwned
{
get
{
return _isOwned;
}
set
{
if(_isOwned!=value)
{
_isOwned= value;
OnPropertyChanged(nameof(IsOwned));
}
}
}
And since you had used MVVM , you should handle the logic in ViewModel instead of Event . Otherwise it will have conflict with the data-binding .
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged([CallerMemberName] string name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
// MySource here is the ItemsSource of CollectionView
public ObservableCollection<MyModel> MySource { get; set; }
public MyViewModel()
{
MySource = new ObservableCollection<MyModel>() {
//...
};
foreach(MyModel model in MySource)
{
model.PropertyChanged += Model_PropertyChanged;
}
}
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName== "IsOwned")
{
// do some thing you want here .
}
}
}