Xamarin 在 ListView 中全选

Posted

技术标签:

【中文标题】Xamarin 在 ListView 中全选【英文标题】:Xamarin Select All in ListView 【发布时间】:2021-11-25 15:39:57 【问题描述】:

我希望有一个全选复选框,当它被选中或取消选中时,它将更新列表视图中的所有其他复选框,但我找不到让它们更新的方法。我尝试了 foreach 语句,以及 ViewModel 中的 for 语句,并在 Select All 复选框更改时运行任务,但它们似乎没有更新 UI。任何帮助都会得到帮助!

查看模型:

 public class SyncViewModel : BaseViewModel
    
        public ObservableCollection<Company> CompaniesCollection  get; set; 
        public ObservableCollection<WellGroup> WellGroupCollection  get; set; 
        public ObservableCollection<Well> WellsCollection  get; set; 

        public SyncViewModel()
        
            Title = "Sync";
            CompaniesCollection = new ObservableCollection<Company>();
            WellGroupCollection = new ObservableCollection<WellGroup>();
            WellsCollection = new ObservableCollection<Well>();
        

        public async Task InitializeData()
        

            var wellDataStore = new WellDataStore();

            var companies = await wellDataStore.GetAllGroups();
            if (companies != null)
            
                CompaniesCollection.Clear();

                foreach (var company in companies)
                
                    CompaniesCollection.Add(company);
                
            

        
        
        public async Task SyncData()
        

            IsBusy = true;

            // load and process data
            IsBusy = false;
            
         
    

xaml:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewModel="clr-namespace:SiteVisits.ViewModels" xmlns:model="clr-namespace:SiteVisits.Models" 
             x:DataType="viewModel:SyncViewModel"
             x:Class="SiteVisits.Views.Sync">

    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Sync" Clicked="Sync_Clicked" />
    </ContentPage.ToolbarItems>
    <StackLayout>
        <ActivityIndicator 
            IsVisible="Binding IsBusy" 
            IsRunning="Binding IsBusy" />
        <CheckBox x:Name="SelectAll" Color="Blue" CheckedChanged="CheckAll"  />
        <Label Text="Select All" FontSize="Large" VerticalOptions="Center"/>
        <ListView x:Name="Companies"
                ItemsSource="Binding CompaniesCollection"
                SelectionMode="Single"
                HasUnevenRows="True"
                ItemTapped="Companies_Selection">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Padding="10" x:DataType="model:Company">
                            <CheckBox x:Name="Name" Color="Blue" IsChecked="Binding IsChecked" />
                            <Label Text="Binding Name" 
                                        FontSize="Large"
                                        VerticalOptions="Center"/>
                        </StackLayout>

                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

xaml.cs:

  SyncViewModel viewModel;
        public Sync(SyncViewModel viewModel)
        
            InitializeComponent();

            this.viewModel = viewModel;
            BindingContext = this.viewModel;
        
       
        protected override async void OnAppearing()
        
            await viewModel.InitializeData();
        

        async private void Sync_Clicked(object sender, EventArgs e)
        
            await viewModel.SyncData(); 
        

        private void Companies_Selection(object sender, ItemTappedEventArgs e)
        

            if (e.Item != null)
            
                var company = e.Item as Company;
                company.IsChecked = !company.IsChecked;
            
        

【问题讨论】:

那叫CheckAll的方法是什么? Companies_Selection 工作了吗? CheckAll 现在什么都不做,但我想这将是我实际选择所有项目时使用的方法。 Companies_Selection 工作正常。 好的。我会发布一些代码供您尝试:) 【参考方案1】:

由于您使用的是 MVVM,我会为复选框使用绑定

    <CheckBox x:Name="SelectAll" Color="Blue" IsChecked="Binding AllChecked"  />

那么你将需要这个 bool 属性,就像这样。所以当值改变时,它会更新所有的集合

    private bool _allChecked;
    public bool AllChecked  get => _allChecked;
        set
        
            if (value != _allChecked)
            
                UpdateCompaniesCollection(value);
                OnPropertyChanged(nameof(AllChecked));
            
        
    

然后您将需要更新集合的方法。一种方法是

    void UpdateCompaniesCollection(bool newValue)
    
        for(int i = 0; i < CompaniesCollection.Count; i++)
        
            var tempCompany = CompaniesCollection[i];
            tempCompany.IsChecked = newValue;
            CompaniesCollection[i] = tempCompany;
        
    

这应该可以解决问题。这只会在选中 Checkbox 时触发集合内元素的更改。但是如果你还想反过来(如果一个项目未选中,则取消选择 allCheck),那就更复杂了。

【讨论】:

以上是关于Xamarin 在 ListView 中全选的主要内容,如果未能解决你的问题,请参考以下文章

Mvvmcross xamarin 在 Listview 模板中形成按钮命令

使用 Laravel 和 Eloquent 从表中全选

在 Windows 中全选和复制的最有效方法

linux:vim中全选复制

从数据库表中全选——但在其中一列上使用函数

MYSQL XDev API Javascript 从表中全选