xamarin - Xamarin.forms - 复选框触发另一个复选框的 CheckedChanged 事件
问题描述
在我的 xamarin.forms 应用程序中,我有一个带有复选框的列表视图,用于选择单个单元格。我要做的是通过在列表视图之外提供“全选”复选框来多选列表视图内的复选框。多选工作正常。对于“全选”复选框单击和单个复选框单击,我正在执行一些操作,例如 API 调用。我面临的问题是每当我单击“全选”复选框时,都会触发单个复选框的复选框更改事件。我知道它很自然但是有什么方法可以阻止它,例如订阅或取消订阅单个复选框的更改事件或某物?
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>
多选复选框选中事件
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();
}
}
单选复选框更改事件
private void Single_CheckedChanged(object sender, CheckedChangedEventArgs e)
{
if (!e.Value)
{
}
else{
PerformSomeAction();
}
}
数据模型
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");
}
}
}
}
解决方案
同意@Nikhileshwar,您可以定义一些属性来获得不同的条件。而且由于您使用过MVVM,您最好将所有逻辑处理都放在您的视图模型中。
在xml中
<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;
}
}
推荐阅读
- r - 如何基于 R 中的 OR 和 AND 语句创建新列?
- google-apps-script - 如何使用 Google Apps 脚本过滤单个列中的多个条件?
- c# - 启动时启动程序时出现拒绝访问错误(C#)
- delphi - Delphi 7 stringGrid第一行内容
- javascript - 使用 Tensorflow JS 执行 mobilenet v2 进行对象检测
- html - 如何在 CSS 网格中动态地流动这些盒子?
- r - 如何获取R中两个表中都不存在的所有行?
- r - 用R中的部分文件名替换主题ID
- java-stream - Kstream 消费者总是重新平衡
- node.js - Dockerizing Sequelize 和 Postgres 不起作用