Xamarin 表单中的多选复选框跨平台

问题描述 投票:0回答:1

下面是我在 Xamarin 表单中用于复选框的代码,但在这里我只能选择一项,我想从复选框中选择多个项目。数据从数据库绑定到该复选框。请帮助我。

Checkforms.xaml.cs

 public partial class Checkforms : ContentPage
    {
        private ObservableCollection<HelperModel> statusRecords;
        string[] statusList;
        public Checkforms()
        {
            InitializeComponent();
            GetUserRoles();
          
        }
        public async void GetUserRoles()
        {
            HttpClient client = new HttpClient();
           var response = await client.GetStringAsync("http://**********/api/Masters/getRoles");
            var details = JsonConvert.DeserializeObject<List<HelperModel>>(response);
            ListView1.ItemsSource = details;

           
        }
        private async void ListView1_ItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            if (e.SelectedItem == null) return;
            var statusData = e.SelectedItem as HelperModel;
            ((ListView)sender).SelectedItem = null;

            HttpClient client = new HttpClient();
            var response = await client.GetStringAsync("http://********/api/Masters/getRoles");
            var details = JsonConvert.DeserializeObject<List<HelperModel>>(response);
            ListView1.ItemsSource = details;

          
            var item = details.Where(x => x.name == statusData.name).FirstOrDefault();
            if (item != null)
                item.IsSelected = !item.IsSelected;
           
        }
    }

支票表格.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Checkbox_listview.Checkforms"
               xmlns:lv="clr-namespace:Xamarin.Forms.MultiSelectListView;assembly=Xamarin.Forms.MultiSelectListView" Padding="0,20,0,0">
    <ContentPage.Content>
        <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <!-- Place new controls here -->
            <ListView x:Name="ListView1" ItemSelected="ListView1_ItemSelected" lv:MultiSelect.Enable="true">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <StackLayout HorizontalOptions="FillAndExpand"
Orientation="Horizontal" Padding="10  ">
                                    <Label Text="{Binding name}" HorizontalOptions="StartAndExpand"/>
                                    <Image Source="select.png"  IsVisible="{Binding IsSelected}"
VerticalOptions="Center"  HeightRequest="40"
WidthRequest="40"/>
                                </StackLayout>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            
        </StackLayout>
</ContentPage.Content>
</ContentPage>

HelperModel.cs

public class HelperModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private bool isSelected = false;
        public string name { get; set; }
        public bool IsSelected
        {
            get { return isSelected; }
            set
            {
                isSelected = value;
                OnPropertyChanged("IsSelected");
            }
        }
        //OnProperty changed method
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

从数据库绑定后,我尝试从复选框中选择多个项目,从这里一次只能选择一个项目。请帮忙如何选择多个项目。

c# asp.net xamarin.forms
1个回答
0
投票

您可以尝试使用

CollectionView
来替换
listview
,如下代码所示。
CollectionView
SelectionMode
,可以设置为
Multiple

  <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <!-- Place new controls here -->
            <CollectionView  x:Name="ListView1" ItemsSource="{Binding StatusRecords}"   SelectionMode="Multiple"
                SelectionChanged="ListView1_SelectionChanged">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        
                                <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10  ">
                                    <Label Text="{Binding name}" HorizontalOptions="StartAndExpand"/>
                                    <Image Source="select.png"  IsVisible="{Binding IsSelected}" VerticalOptions="Center"  HeightRequest="40" WidthRequest="40"/>
                                </StackLayout>
                          
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

        </StackLayout>

这是正在运行的 GIF。

==========更新================ 您想要多重预选结果吗?

如果是这样,您应该在 ViewModel 中添加该属性。注意:无论您的机型是什么,请将

ObservableCollection
类型设置为
object

   ObservableCollection<object> selectedHelperModels;
        public ObservableCollection<object> SelectedHelperModels
        {
            get
            {
                return selectedHelperModels;
            }
            set
            {
                if (selectedHelperModels != value)
                {
                    selectedHelperModels = value;
                    OnPropertyChanged("SelectedHelperModels");
                }
            }
        }

然后如果

IsSelected
选择为 true。我会将其添加到
SelectedHelperModels

  public MyHelperViewModel()
        {

           
            StatusRecords = new ObservableCollection<HelperModel>();
            StatusRecords.Add(new HelperModel() { IsSelected=false, name="test1" });
            StatusRecords.Add(new HelperModel() { IsSelected = true, name = "test2" });
            StatusRecords.Add(new HelperModel() { IsSelected = true, name = "test3" });
            StatusRecords.Add(new HelperModel() { IsSelected = true, name = "test4" });
            StatusRecords.Add(new HelperModel() { IsSelected = false, name = "test5" });
            StatusRecords.Add(new HelperModel() { IsSelected = false, name = "test6" });

           
            SelectedHelperModels = new ObservableCollection<object>();


            foreach (var item in StatusRecords)
            {
                if (item.IsSelected)
                {
                    SelectedHelperModels.Add(item);
                }
            }
        }
       

在前台xaml中。在

SelectedItems="{Binding SelectedHelperModels}"
中添加
CollectionView

 <CollectionView  x:Name="ListView1" ItemsSource="{Binding StatusRecords}"   SelectedItems="{Binding SelectedHelperModels}" SelectionMode="Multiple"
                SelectionChanged="ListView1_SelectionChanged">
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        
                        <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10  ">
                            <Label Text="{Binding name}" HorizontalOptions="StartAndExpand"/>
                            <Image Source="{Binding IsSelected, Converter={StaticResource imageToBool}}"  IsVisible="{Binding IsSelected} " VerticalOptions="Center"  HeightRequest="40" WidthRequest="40"/>
                        </StackLayout>
                          
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>

当您发表评论时,您缺少

ListView1_SelectionChanged
事件。只需在布局背景代码中添加即可。

  public partial class MainPage : ContentPage
    {
        MyHelperViewModel myHelperViewModel;
        public MainPage()
        {
            InitializeComponent();
            myHelperViewModel=  new MyHelperViewModel();
            this.BindingContext = myHelperViewModel;
        }

        

        private void ListView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            
        }
    }
}

==========更新2============

你想达到下面GIF的效果吗?

如果是这样,我发现

SelectionChanged
事件无法轻易实现,并且无法满足MVVM要求,所以我在
TapGestureRecognizer
中为
StackLayout
添加了一个
CollectionView

这是代码。

<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">

            <CollectionView  x:Name="ListView1" 
                             ItemsSource="{Binding StatusRecords}" 
                            
                            
                             SelectedItems="{Binding SelectedHelperModels}" 
                             SelectionMode="Multiple"
                            >
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10">
                            <StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Command="{Binding  BindingContext.ChangeCommand, Source={x:Reference Name=ListView1}}"
                                                      CommandParameter="{Binding .}"
                                                      />


                            </StackLayout.GestureRecognizers>
                            <Label Text="{Binding name}" HorizontalOptions="StartAndExpand"/>
                            <Image Source="{Binding IsSelected, Converter={StaticResource imageToBool},Mode=TwoWay}"  IsVisible="{Binding IsSelected, Mode=TwoWay}" VerticalOptions="Center"  HeightRequest="40" WidthRequest="40"/>
                        </StackLayout>
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </StackLayout>

这是 ViewModel。

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;

namespace SelectMutiPlyDemo
{
    public class MyHelperViewModel: INotifyPropertyChanged
    {
        public ObservableCollection<HelperModel> StatusRecords { get; set; }
        public ICommand ChangeCommand { protected set; get; }
        ObservableCollection<object> selectedHelperModels;
        public ObservableCollection<object> SelectedHelperModels
        {
            get
            {
                return selectedHelperModels;
            }
            set
            {
                if (selectedHelperModels != value)
                {
                    selectedHelperModels = value;
                    OnPropertyChanged("SelectedHelperModels");
                }
            }
        }
        public MyHelperViewModel()
        {

           
            StatusRecords = new ObservableCollection<HelperModel>();
            StatusRecords.Add(new HelperModel() { IsSelected=false, name="test1" });
            StatusRecords.Add(new HelperModel() { IsSelected = true, name = "test2" });
            StatusRecords.Add(new HelperModel() { IsSelected = true, name = "test3" });
            StatusRecords.Add(new HelperModel() { IsSelected = true, name = "test4" });
            StatusRecords.Add(new HelperModel() { IsSelected = false, name = "test5" });
            StatusRecords.Add(new HelperModel() { IsSelected = false, name = "test6" });
     
            SelectedHelperModels = new ObservableCollection<object>();

            foreach (var item in StatusRecords)
            {
                if (item.IsSelected)
                {
                    SelectedHelperModels.Add(item);
                }
            }

            ChangeCommand=new Command<HelperModel>((key) =>
            {
                if (SelectedHelperModels.Contains<object>(key))
                {
                    SelectedHelperModels.Remove(key);
                   
                }
                else
                {
                    SelectedHelperModels.Add(key);
                    
                }
                key.IsSelected = !key.IsSelected;


            });
        }
       
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        #endregion
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.