Reputation: 120
Is there a way in .NET MAUI to toggle the state of a checkbox when the label next to it is clicked? As an example:
<?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>
Upvotes: 3
Views: 8781
Reputation: 1734
You can use TapGestureRecognizer
to manually toggle the checkbox when the label is tapped:
<Label Text="Click Me">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnLabelClicked" />
</Label.GestureRecognizers>
</Label>
private void OnLabelClicked(object sender, EventArgs e)
{
CheckBox.IsChecked = !CheckBox.IsChecked;
}
To make it simpler, you could define a custom View:
<?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);
}
}
You can then use the view:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns:custom="clr-namespace:[NAMESPACE]">
<custom:CheckBoxLabeled Text="Click Me" CheckedChanged="OnClickMeCheckChanged" />
Note: Replace [NAMESPACE]
with your project namespace!
Upvotes: 0
Reputation: 23
For anyone still interested, I just put both label and checkbox in a grid. Checkbox has to be last, so that it is drawn over the label. This way, click will be recognized directly by checkbox, no code behind needed. They both have to be same width, so they are drawn over the same space.
<Grid>
<Label
WidthRequest="160"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
Text="Live Update" />
<CheckBox
WidthRequest="160"
IsChecked="{Binding IsLiveUpdate}"
VerticalOptions="Center" />
</Grid>
Upvotes: 2
Reputation: 11
//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;
}
}
Upvotes: 1
Reputation: 16459
Basically you need to do something like this:
<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>
And then in your VM, all you need to do is:
SomeThingTappedCommand = new Command(() => IsChecked = !IsChecked);
Where IsChecked is a notifiable property:
private bool isChecked;
public bool IsChecked
{
get => isChecked;
set => SetProperty(ref isChecked, value);
}
Upvotes: 2
Reputation: 1609
In the xamarin file:
<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>
And in code behind:
private void Clicked(object sender, EventArgs e)
{
myCheckBox.IsChecked = !myCheckBox.IsChecked;
}
Upvotes: 2
Reputation: 2216
You can use it like this , a Label and a CheckBox.
Give the CheckBox a Name.
<Label
Text="Check this box"
FontSize="32"
HorizontalOptions="Center" >
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
NumberOfTapsRequired="1" />
</Label.GestureRecognizers>
</Label>
<CheckBox x:Name="StackO" />
Then for the Label Tap
private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
{
if (StackO.IsChecked )
StackO.IsChecked = false;
else
StackO.IsChecked = true;
}
Upvotes: 0