首页 > 解决方案 > 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");
                    }
                }
            }
        }

标签: xamarinxamarin.forms

解决方案


同意@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;
        }
    }

推荐阅读