Reputation: 25
This is my first time working on a MAUI app and struggling with a scenario where I need to capture the selected CheckBox items from a collection and store their relevant Section objects into a list when I click a button (I've seen some people add to the model boolean property to see if the item is selected or not but i didn't do that) .
I have a CollectionView that displays a list of Sections:
<CollectionView ItemsSource="{Binding Sections}"
Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout>
<!-- I don't know what to add to the check box to handle the selecting event -->
<CheckBox Color="#0B4C90"/>
<Label Text="{Binding SectionName}"
FontSize="20"
FontAttributes="Bold"
TextColor="#0B4C90"/>
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Border>
<Buton Text="Get Sections"/>
Here is the Section Model : (i called it 'Rayon' because it wouldn't let me name it Section)
public class Rayon
{
[Key]
public int Id { get; set; }
public string SectionName { get; set; } = null!;
public ICollection<SectionSupplier> SectionSuppliers { get; set; } = null!;
public ICollection<Product> Products { get; set; } = null!;
}`
And here is my view model :
`public partial class CreateSupplierPageViewModel : ObservableObject
{
/* This is the list that i want to Add or remove Sections from whenever i check or uncheck one of the checkboxs */
private ObservableCollection<Rayon> _selectedSections;
public ObservableCollection<Rayon> SelectedSections
{
get => _selectedSections;
set
{
_selectedSections = value;
}
}
public ObservableCollection<Rayon> Sections { get; set; } = new ObservableCollection<Rayon>();
public async Task GetSectionsList()
{
var sectionList = new List<Rayon>();
var sectionUrl = "https://localhost:7282/api/Sections/GetSections";
using (var client = new HttpClient())
{
var Apiresponse = await client.GetAsync(sectionUrl);
if (Apiresponse.StatusCode == System.Net.HttpStatusCode.OK)
{
var content = await Apiresponse.Content.ReadAsStringAsync();
sectionList = JsonConvert.DeserializeObject<List<Rayon>>(content);
}
}
if (sectionList?.Count > 0)
{
foreach (var section in sectionList)
{
Sections.Add(section);
}
}
}
/*This method is used simply because i couldn't call GetSectionsList directly in the constructor to avoid deadlocks */
public static async Task<CreateSupplierPageViewModel> Create()
{
var it = new CreateSupplierPageViewModel();
await it.Initialize();
return it;
}
private async Task Initialize()
{
await GetSectionsList();
}
public CreateSupplierPageViewModel()
{
SelectedSections = new ObservableCollection<Rayon>();
}
}
I'm looking for guidance on how to capture the selected Sections when the button is clicked. Any help or code samples would be greatly appreciated. Thank you!
I tried Looking in the net for a solution but whatever i find just confuses me because i don't know what or where should i place the code that i find in the solutions . i tried also using chat gpt but it whatever solution it provides it doesn,t work
Upvotes: 1
Views: 1880
Reputation: 13879
Yes, you can add a bool field to the model (Rayon.cs
) of list Sections
and bind it to the CheckBox
. This is also the method we often use.
Of course, if you really want to trigger the selecting event, you can use EventToCommandBehavior to achieve this.
I created a demo and tried to achieve this function with two methods above.
You can refer to the following code:
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewdels="clr-namespace:MauiCheckListviewApp.ViewModes"
xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="MauiCheckListviewApp.MainPage">
<ContentPage.BindingContext>
<viewdels:MyViewModel></viewdels:MyViewModel>
</ContentPage.BindingContext>
<VerticalStackLayout>
<CollectionView ItemsSource="{Binding Sections}" x:Name="myCollectionView"
Grid.Row="1">
<CollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout>
<CheckBox Color="#0B4C90" IsChecked="{Binding IsChecked}">
<CheckBox.Behaviors>
<toolkit:EventToCommandBehavior
Command="{Binding BindingContext.UpdateThisItemCommand, Source={x:Reference myCollectionView}}"
CommandParameter="{Binding .}"
EventName="CheckedChanged" />
</CheckBox.Behaviors>
</CheckBox>
<Label Text="{Binding SectionName}"
FontSize="20"
FontAttributes="Bold"
TextColor="#0B4C90"/>
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
<Button Text="Get Sections" Command="{Binding GetResultCommand}"/>
</VerticalStackLayout>
</ContentPage>
MyViewModel.cs
public class MyViewModel
{
public ObservableCollection<Rayon> Sections { get; set; } = new ObservableCollection<Rayon>();
public ICommand GetResultCommand { get; set; }
public ICommand UpdateThisItemCommand { get; set; }
public MyViewModel() {
Sections.Add(new Rayon { SectionName= "section_1"});
Sections.Add(new Rayon { SectionName= "section_2"});
Sections.Add(new Rayon { SectionName= "section_3"});
GetResultCommand = new Command(getResult);
UpdateThisItemCommand = new Command<Rayon>(checkboxcommand);
}
private void checkboxcommand(Rayon obj)
{
if (obj != null)
{
if (obj.IsChecked)
{
// you also need to add some other logic codes here
}
}
}
private void getResult()
{
foreach (var section in Sections)
{
if (section.IsChecked) {
System.Diagnostics.Debug.WriteLine(section.SectionName);
}
}
}
}
Rayon.cs
public class Rayon: INotifyPropertyChanged
{
public string SectionName { get; set; }
private bool _isChecked;
public bool IsChecked
{
set { SetProperty(ref _isChecked, value); }
get { return _isChecked; }
}
bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value))
return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
Note:
Here, we need to install nuget CommunityToolkit.Maui
and initialize the package correctly.
For more information, you can check document: Get started.
Upvotes: 1