In my xamarin.forms app, I have a listview with checkboxes for the selection of the individual cell. What I am trying to do is multi select the checkboxes inside the listview by providing a "select all" checkbox outside the listview.The Multiselection works fine. For the "select all" checkbox click and individual checkbox click, I am performing some actions like an API Call. The Problem I am facing is Whenever I Click on the "select all" checkbox, the checkbox changed event of individual checkbox gets triggered.I know its natural But is there any way to prevent it like subscribe or unsubscribe the changed event of individual checkbox or something?

Xaml
<Grid >
<Grid.RowDefinitions>
<RowDefinitions Height="Auto"/>
<RowDefinitions Height="Auto"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Orientation="Horizontal">
<Label Text="Select All" FontSize="Micro" TextColor="LawnGreen" HorizontalOptions="Start" VerticalOptions="Center" >
</Label>
<CheckBox x:Name="MultiselectCheckbox" ScaleX="0.8" ScaleY="0.8" CheckedChanged="MultiSelectCheckBox_CheckedChanged" IsChecked="False" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Color="LawnGreen"></CheckBox>
</StackLayout>
<ListView
x:Name="Listview"
HorizontalOptions="FillAndExpand"
ItemTapped="DistrictList_ItemTapped"
VerticalOptions="FillAndExpand" >
<ListView.ItemTemplate >
<DataTemplate >
<ViewCell >
<ViewCell.View>
<Frame HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="{Binding name}" FontSize="Micro" HorizontalOptions="StartAndExpand" VerticalOptions="Center" TextColor="Snow" Margin="5,0,0,0">
</Label>
<CheckBox CheckedChanged="Single_CheckedChanged" IsChecked="{Binding Selected}" Color="LightBlue" HorizontalOptions="End" >
</CheckBox>
</StackLayout>
</Frame>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Multiselect Checkbox checked event
private void MultiSelectCheckBox_CheckedChanged(object sender, CheckedChangedEventArgs e)
{
if (!e.Value)
{
foreach (MyData TS in MyObject)
{
TS.Selected = false;
}
}
else{
foreach (MyData TS in MyObject)
{
TS.Selected = true;
}
PerformSomeAction();
}
}
Single selection Checkbox changed event
private void Single_CheckedChanged(object sender, CheckedChangedEventArgs e)
{
if (!e.Value)
{
}
else{
PerformSomeAction();
}
}
Data Model
public class MyData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string name { get; set; }
private bool selected;
public bool Selected
{
get
{
return selected;
}
set
{
if (value != null)
{
selected = value;
NotifyPropertyChanged("Selected");
}
}
}
}
Agree with @ Nikhileshwar , you could define some properties to get the different condition .And since you had used MVVM, you would better put all logic handling in your viewmodel .
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Orientation="Horizontal" HeightRequest="40" BackgroundColor="LightPink">
<Label Text="Select All" FontSize="Micro" TextColor="Red" HorizontalOptions="Start" VerticalOptions="Center" >
</Label>
<CheckBox x:Name="MultiselectCheckbox" ScaleX="0.8" ScaleY="0.8" IsChecked="{Binding MultiselectCheck}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Color="Red"></CheckBox>
</StackLayout>
<ListView Grid.Row="1"
x:Name="Listview"
HorizontalOptions="FillAndExpand"
ItemsSource="{Binding MyItems}"
VerticalOptions="FillAndExpand" >
<ListView.ItemTemplate >
<DataTemplate >
<ViewCell >
<Frame Padding="0" HeightRequest="40" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand">
<Label Text="{Binding name}" FontSize="Micro" HorizontalOptions="StartAndExpand" VerticalOptions="Center" TextColor="Red" Margin="5,0,0,0">
</Label>
<CheckBox IsChecked="{Binding Selected}" Color="Red" HorizontalOptions="End" >
</CheckBox>
</StackLayout>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
public class MyViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
bool isMultiselect;
bool isSingleSelect;
public ObservableCollection<MyData> MyItems { get; set; }
private bool multiselectCheck;
public bool MultiselectCheck
{
get
{
return multiselectCheck;
}
set
{
if (multiselectCheck != value)
{
multiselectCheck = value;
if(!isSingleSelect)
{
isMultiselect = true;
foreach (MyData data in MyItems)
{
data.Selected = value;
}
isMultiselect = false;
}
NotifyPropertyChanged("MultiselectCheck");
}
}
}
public MyViewModel()
{
MyItems = new ObservableCollection<MyData>() {
new MyData(){name="Selection1" },
new MyData(){name="Selection2" },
new MyData(){name="Selection3" },
};
foreach(MyData data in MyItems)
{
data.PropertyChanged += Data_PropertyChanged;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With