I'm having this problem with a custom view I made that connects a checkbox with a text and allows you to tap the entire view to tick the checkbox. But when I bind to the exposed binding from the checkbox It doesn't seem to react to changes. I'm clearly not understanding something and was hoping maybe someone here can see that obvious thing I am missing. A normal checkbox works just fine.
I looked at several of the solutions on site and tried a few of the things I found but alas, no dice.
xaml:
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Celery.Controls.CheckboxWithTextControl">
<ContentView.Content>
<Grid ColumnDefinitions="*,48">
<Grid.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped"/>
</Grid.GestureRecognizers>
<Label x:Name="DisplayedLabel"
HorizontalTextAlignment="Start"
VerticalTextAlignment="Center"/>
<CheckBox x:Name="DisplayedCheckbox"
Grid.Column="1"
HorizontalOptions="Center"
VerticalOptions="Center">
<VisualStateManager.VisualStateGroups>
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal">
<VisualState.Setters>
<Setter Property="Color" Value="{StaticResource TextColour}"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="IsChecked">
<VisualState.Setters>
<Setter Property="Color" Value="{StaticResource SecondryTextColor}"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</VisualStateManager.VisualStateGroups>
</CheckBox>
</Grid>
</ContentView.Content>
</ContentView>
cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Celery.Controls
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class CheckboxWithTextControl : ContentView
{
public static readonly BindableProperty TextProperty =
BindableProperty.Create("Text", typeof(string), typeof(CheckboxWithTextControl),"Default", BindingMode.OneWay,
propertyChanged: (bindable, oldValue, newValue) =>
{
if (newValue != null && bindable is CheckboxWithTextControl control)
{
control.DisplayedLabel.Text = (string)newValue;
}
});
public static readonly BindableProperty IsCheckedProperty =
BindableProperty.Create("IsChecked", typeof(bool), typeof(CheckboxWithTextControl),false , BindingMode.TwoWay,
propertyChanged: (BindableObject bindable, object oldValue, object newValue) =>
{
if (newValue != null && bindable is CheckboxWithTextControl control)
{
control.DisplayedCheckbox.IsChecked = (bool)newValue;
}
});
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
public CheckboxWithTextControl()
{
InitializeComponent();
}
private void OnTapped(object sender, EventArgs e)
{
IsChecked = !IsChecked;
}
}
}
EDIT 1: I found out that if I tap the checkbox itself it breaks, but tapping anyother part of the screen works.
I changed the checkbox to also update the exposed bindable when it updates as such
private void OnCheckedChange(object sender, CheckedChangedEventArgs e)
{
if (IsChecked != e.Value) IsChecked = e.Value;
}
and the checkbox is now
<CheckBox x:Name="DisplayedCheckbox"
Grid.Column="1"
HorizontalOptions="Center"
VerticalOptions="Center"
CheckedChanged="OnCheckedChange">