MAUI自定义控件HandleCheckBoxCommand绑定失效问题求助
问题:自定义控件中CheckBox的命令无法触发
我开发了一个代表会议室结构的自定义控件,包含会议室名称、用户列表以及用于邀请用户的复选框。控件能正常显示用户列表、设置会议室名称,但HandleCheckBoxCommand始终无法触发。
自定义控件XAML代码
<StackLayout> <inputLayout:SfTextInputLayout Hint="{Binding Hint, Source={x:Reference UserExpander}}" HorizontalOptions="StartAndExpand" OutlineCornerRadius="8"> <Entry Text="{Binding RoomName, Source={x:Reference UserExpander}}" /> </inputLayout:SfTextInputLayout> <expander:SfExpander> <expander:SfExpander.Header> <Grid ColumnDefinitions="50,60" ColumnSpacing="10"> <Label FontFamily="Mat" FontSize="Header" HorizontalTextAlignment="Center" Text="{Static helpers:IconFont.Group}" VerticalTextAlignment="Center" /> <Label Grid.Column="1" Text="Students" /> </Grid> </expander:SfExpander.Header> <expander:SfExpander.Content> <CollectionView ItemsSource="{Binding Users, Source={x:Reference UserExpander}}" SelectionMode="None"> <CollectionView.ItemTemplate> <DataTemplate> <Border Margin="2"> <Border.StrokeShape> <RoundRectangle CornerRadius="8" /> </Border.StrokeShape> <Grid Margin="5,5,5,0" ColumnDefinitions="40,*" RowDefinitions="*,*"> <Label Grid.Column="1" Text="{Binding Name}" /> <Label Grid.Row="3" Grid.Column="1" Text="{Binding Email}" /> <chechbox:SfCheckBox Grid.RowSpan="3" HorizontalOptions="End" IsChecked="{Binding IsParticipant}" VerticalOptions="End"> <chechbox:SfCheckBox.GestureRecognizers> <TapGestureRecognizer Command="{Binding HandleCheckBoxCommand, Source={RelativeSource AncestorType={x:Type ContentView}}}" CommandParameter="{Binding .}" /> </chechbox:SfCheckBox.GestureRecognizers> </chechbox:SfCheckBox> </Grid> </Border> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </expander:SfExpander.Content> </expander:SfExpander> </StackLayout> </ContentView>
自定义控件后台代码
public partial class UserDetailsExpander : ContentView { public UserDetailsExpander() { InitializeComponent(); } public static readonly BindableProperty HintProperty = BindableProperty.Create( nameof(Hint), typeof(string), typeof(UserDetailsExpander)); public string Hint { get => (string)GetValue(HintProperty); set => SetValue(HintProperty, value); } public static readonly BindableProperty RoomNameProperty = BindableProperty.Create( nameof(RoomName), typeof(string), typeof(UserDetailsExpander), string.Empty, BindingMode.TwoWay); public string RoomName { get => (string)GetValue(RoomNameProperty); set => SetValue(RoomNameProperty, value); } public static readonly BindableProperty UsersProperty = BindableProperty.Create( nameof(Users), typeof(IEnumerable), typeof(UserDetailsExpander)); public IEnumerable Users { get => (IEnumerable)GetValue(UsersProperty); set => SetValue(UsersProperty, value); } public static readonly BindableProperty HandleCheckBoxCommandProperty = BindableProperty.Create( nameof(HandleCheckBoxCommand), typeof(RelayCommand), typeof(UserDetailsExpander)); public RelayCommand HandleCheckBoxCommand { get => (RelayCommand)GetValue(HandleCheckBoxCommandProperty); set => SetValue(HandleCheckBoxCommandProperty, value); } }
页面中使用自定义控件的代码
<ContentPage x:Class="DemyAI.Views.NewTestPage" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:controls="clr-namespace:DemyAI.Controls" xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" xmlns:vm="clr-namespace:DemyAI.ViewModels" x:DataType="vm:NewTestPageViewMode"> <ContentPage.Behaviors> <mct:EventToCommandBehavior Command="{Binding AppearingCommand}" EventName="Appearing" /> </ContentPage.Behaviors> <VerticalStackLayout Margin="10"> <controls:UserDetailsExpander HandleCheckBoxCommand="{Binding HandleCheckBoxCommand}" Hint="Name of the test" RoomName="{Binding RoomName}" Users="{Binding Users}" /> <Button Command="{Binding StartMeetingCommand}" /> </VerticalStackLayout> </ContentPage>
ViewModel代码
public ObservableCollection<User> Users { get; set; } = []; public ObservableCollection<User> Invited { get; set; } = []; [ObservableProperty] string? roomName; [RelayCommand] async Task Appearing() { await GetStudents(); } private async Task GetStudents() { Users.Clear(); var data = await dataService.GetByRole<User>("Users", Roles.Student.ToString()); foreach(var filterUser in data) { Users.Add(filterUser); } } [RelayCommand] void HandleCheckBox(User user) { if(user.IsParticipant) { Invited.Add(user); } else { Invited.Remove(user); } } [RelayCommand] async Task StartMeeting() { if(string.IsNullOrEmpty(RoomName)) { await appService.DisplayAlert("Error", "The room name cannot be empty", "OK"); return; } var loogedUser = await authenticationService.GetLoggedInUser(); var databaseUer = await dataService.GetByUidAsync<User>("Users", loogedUser!.Uid); var meetingOptions = new MeetingOptions { EnableAdvancedChat = true, EnableEmojiReactions = true, EnableNoiseCancellationUi = true, EnableHandRaising = true, EnablePrejoinUi = true, EnablePipUi = true, EnableScreenshare = true, EnableVideoProcessingUi = true, EnablePeopleUi = false, EnableChat = true // Set other meeting option properties as needed }; try { var roomURL = await meetingService.CreateMeetingAsync(RoomName, meetingOptions, Constants.DAILY); foreach(var userInvited in Invited) { string userEmail = userInvited.Email; await EmailHelper.SendEmail(userEmail, RoomName, databaseUer, roomURL, null); } } catch(Exception ex) { await appService.DisplayAlert("Error", $"Error creating meeting: {ex.Message}", "OK"); } }
已尝试的解决方法
- 使用祖先类型绑定
- 命名控件绑定
- 设置双向绑定
- 使用
BindingContext.HandleCheckBoxCommand绑定
期望点击复选框时触发HandleCheckBox命令,但所有尝试均未解决问题。
内容的提问来源于stack exchange,提问作者Natash Dimas
相关产品推荐
相关产品推荐

