Xamarin在ListView中选择全部



我希望有一个选择所有复选框,将更新所有其他复选框在列表视图中,当它被选中或取消选中,但我找不到一种方法来使它们更新。我试一个foreach语句,以及语句的视图模型和运行任务选择所有复选框时改变,但他们似乎不更新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;
}
}

由于您使用的是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),则会更复杂。

最新更新