.NET MAUI:单击标签时选中复选框



.NET MAUI 中有没有办法在单击复选框旁边的标签时切换复选框的状态?举个例子:

<?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"
x:Class="MyApp.Views.Test"
Title="Test">
<HorizontalStackLayout>
<CheckBox />
<Label Text="Check this box" VerticalOptions="Center" />
</HorizontalStackLayout>
</ContentPage>

基本上你需要做这样的事情:

<ContentView
Padding="10,20">
<ContentView.GestureRecognizers>
<TapGestureRecognizer Command="{Binding SomeThingTappedCommand}" />
</ContentView.GestureRecognizers>
<StackLayout Orientation="Horizontal">
<Label
HorizontalOptions="StartAndExpand"
InputTransparent="True"
Text="Some Title"
VerticalTextAlignment="Center" />
<controls:ExtendedCheckBox
InputTransparent="True"
IsChecked="{Binding IsChecked}"
VerticalOptions="Center"
Color="{DynamicResource PrimaryColor}" />
</StackLayout>
</pan:PancakeView>

然后在 VM 中,您需要做的就是:

SomeThingTappedCommand = new Command(() => IsChecked = !IsChecked);

如果 IsChecked 是应通知属性:

private bool isChecked;
public bool IsChecked
{
get => isChecked;
set => SetProperty(ref isChecked, value);
}

在 xamarin 文件中:

<StackLayout Orientation="Horizontal">
<CheckBox x:Name="myCheckBox"
IsChecked="{Binding IsChecked,Mode=TwoWay}">
</CheckBox>
<Label VerticalTextAlignment="Center"  Text="Test">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="Clicked"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>

在代码隐藏中:

private void Clicked(object sender, EventArgs e)
{
myCheckBox.IsChecked = !myCheckBox.IsChecked;
}

//xaml

<HorizontalStackLayout>
<HorizontalStackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</HorizontalStackLayout.GestureRecognizers>
<CheckBox IsChecked="True" VerticalOptions="Center" />
<Label Text="Hello" VerticalOptions="Center" />
</HorizontalStackLayout>

Xaml.cs

private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
var layout = sender as Layout;
var check = layout.FirstOrDefault(c => c.GetType() == typeof(CheckBox));
if (check != null)
{
((CheckBox)check).IsChecked = !((CheckBox)check).IsChecked;
}
}

对于仍然感兴趣的人,我只是将标签和复选框放在网格中。 复选框必须是最后一个,以便将其绘制在标签上。这样,点击将直接通过复选框识别,无需隐藏代码。它们都必须是相同的宽度,因此它们被绘制在相同的空间上。

<Grid>
<Label
WidthRequest="160"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
Text="Live Update" />
<CheckBox
WidthRequest="160"
IsChecked="{Binding IsLiveUpdate}"
VerticalOptions="Center" />
</Grid>

你可以像这样使用它,一个标签和一个复选框。

为复选框命名。

<Label
Text="Check this box"
FontSize="32"
HorizontalOptions="Center" >
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
NumberOfTapsRequired="1" />
</Label.GestureRecognizers>
</Label>

<CheckBox x:Name="StackO" />

然后对于标签点击

private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
if (StackO.IsChecked )
StackO.IsChecked = false;
else
StackO.IsChecked = true;
}

您可以使用TapGestureRecognizer在点击标签时手动切换复选框:

<Label Text="Click Me">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnLabelClicked" />
</Label.GestureRecognizers>
</Label>
private void OnLabelClicked(object sender, EventArgs e)
{
CheckBox.IsChecked = !CheckBox.IsChecked;
}

为了更简单,您可以定义一个自定义视图:

<?xml version="1.0" encoding="utf-8" ?>
<HorizontalStackLayout xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="[NAMESPACE].CheckBoxLabeled"
x:Name="this">

<CheckBox
x:Name="CheckBox"
CheckedChanged="OnCheckChanged" />
<Label
Text="{Binding Source={x:Reference this}, Path=Text}"
VerticalOptions="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnLabelClicked" />
</Label.GestureRecognizers>
</Label>
</HorizontalStackLayout>
using OnCheckedChanged = System.EventHandler<Microsoft.Maui.Controls.CheckedChangedEventArgs>;
namespace [NAMESPACE];
public partial class CheckBoxLabeled : HorizontalStackLayout
{
public static readonly BindableProperty TextProperty = BindableProperty.Create(
propertyName: nameof(Text),
returnType: typeof(string),
declaringType: typeof(CheckBoxLabeled),
defaultValue: "",
defaultBindingMode: BindingMode.OneWay);
public string Text
{
get => (string)GetValue(TextProperty);
set { SetValue(TextProperty, value); }
}
public event OnCheckedChanged CheckedChanged;
public bool IsChecked => CheckBox.IsChecked;
public CheckBoxLabeled()
{
InitializeComponent();
}
private void OnLabelClicked(object sender, EventArgs e)
{
CheckBox.IsChecked = !CheckBox.IsChecked;
}
private void OnCheckChanged(object sender, CheckedChangedEventArgs e)
{
CheckedChanged?.Invoke(this, e);
}
}

然后,您可以使用该视图:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns:custom="clr-namespace:[NAMESPACE]">
<custom:CheckBoxLabeled Text="Click Me" CheckedChanged="OnClickMeCheckChanged" />

注意:将[NAMESPACE]替换为您的项目命名空间!

最新更新