C# – How to add Checkbox in Xamarin.Forms in Xaml file

c++checkboxxamarin.iosxaml

I'm completely new to xamarin.forms, I need to add a checkbox, radio buttons and drop down list. I tried some samples from net but I'm not able to get the checkbox. Can anyone help me to achieve this in xamarin.forms?

Xaml file

<toolkit:CheckBox Text ="Employee"
                  FontSize="20"
                  CheckedChanged ="OnClicked"/>

or

<controls:CheckBox DefaultText="Default text"
                               HorizontalOptions="FillAndExpand"
                               TextColor="Green"
                               FontSize="25"
                               FontName="AmericanTypewriter"/>

Some links or sample code will make it easier to understand.

Best Solution

I found a better way to do this which is to create your own. It was really quite simple. Create a cs file in a Resources project (or where ever you want) called CheckBox and paste this code:

namespace Resources.Controls
{

public class Checkbox : Button 
{
    public Checkbox()
    {
        base.Image = "Image_Unchecked.png";
        base.Clicked += new EventHandler(OnClicked);
        base.SizeChanged += new EventHandler(OnSizeChanged);
        base.BackgroundColor = Color.Transparent;
        base.BorderWidth = 0;
    }

    private void OnSizeChanged(object sender, EventArgs e)
    {
        //if (base.Height > 0)
        //{
        //    base.WidthRequest = base.Height;
        //}
    }

    public static BindableProperty CheckedProperty = BindableProperty.Create(
        propertyName: "Checked",
        returnType: typeof(Boolean?),
        declaringType: typeof(Checkbox),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: CheckedValueChanged);

    public Boolean? Checked
    {
        get
        {
            if (GetValue(CheckedProperty) == null)
            {
                return null;
            }
            return (Boolean)GetValue(CheckedProperty);
        }
        set
        {
            SetValue(CheckedProperty, value);
            OnPropertyChanged();
            RaiseCheckedChanged();
        }
    }

    private static void CheckedValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (newValue != null && (Boolean)newValue == true)
        {
            ((Checkbox)bindable).Image = "Image_Checked.png";
        }
        else
        {
            ((Checkbox)bindable).Image = "Image_Unchecked.png";
        }
    }

    public event EventHandler CheckedChanged;
    private void RaiseCheckedChanged()
    {
        if (CheckedChanged != null)
            CheckedChanged(this, EventArgs.Empty);
    }

    private Boolean _IsEnabled = true;
    public Boolean IsEnabled
    {
        get
        {
            return _IsEnabled;
        }
        set
        {
            _IsEnabled = value;
            OnPropertyChanged();
            if (value == true)
            {
                this.Opacity = 1;
            }
            else
            {
                this.Opacity = .5;
            }
            base.IsEnabled = value;
        }
    }

    public void OnEnabled_Changed()
    {

    }

    public void OnClicked(object sender, EventArgs e)
    {
        Checked = !Checked;

        // Call the base class event invocation method.
        //base.Clicked(sender, e);
    }

}
}

There is probably a better way to do this but I just added the two images to the appropriate locations in each project (base for UWP, Resources/Drawable for Android).

enter image description here

Then to use it in your Xaml just do something like this (I used a converter bc I was binding to a string value):

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:Resources.Controls;assembly=Resources"
             x:Class="MyNameSpace.CheckBoxExamplePage"
             Title=" Hygiene">
  <Grid Padding="1">
    <ScrollView Padding="4">
      <StackLayout>
        <StackLayout Orientation="Horizontal">
          <controls:Checkbox x:Name="cbHello" Text="Hello CheckBox" Checked="{Binding Path=My.Binding.Path, Converter={StaticResource StringToBoolean}, Mode=TwoWay}" />
        </StackLayout>
        <StackLayout Orientation="Horizontal" Padding="16,0,0,0">
          <controls:Checkbox x:Name="cbDisabled" Text="Disabled Example" IsEnabled="False" Checked="{Binding Path=My.Binding.PathTwo, Converter={StaticResource StringToBoolean}, Mode=TwoWay}" />
        </StackLayout>
      </StackLayout>
    </ScrollView>
  </Grid>
</ContentPage>

Note: You must set the BindingContext in your pages cs file for the check to work. So your Pages code behind file should look like this:

namespace MyNameSpace
{
    public partial class CheckBoxExamplePage
    {
        public CheckBoxExamplePage(object MyBindingObject)
        {
            InitializeComponent();

            this.BindingContext = MyBindingObject;
        }
    }
}

And this is the result!

enter image description here

Hope this helps someone!!

UPDATE:

The following is new code that removes the gray background on disabled and also allows text to wrap if it does not fit on the screen. This uses a ContentView that contains a grid that can expand based on the content.

    public class Checkbox : ContentView
{
    protected Grid ContentGrid;
    protected ContentView ContentContainer;
    public Label TextContainer;
    protected Image ImageContainer;

    public Checkbox()
    {
        var TapGesture = new TapGestureRecognizer();
        TapGesture.Tapped += TapGestureOnTapped;
        GestureRecognizers.Add(TapGesture);

        ContentGrid = new Grid
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand
        };

        ContentGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(42) });
        ContentGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        ContentGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });

        ImageContainer = new Image
        {
            VerticalOptions = LayoutOptions.Center,
            HorizontalOptions = LayoutOptions.Center,
        };
        ImageContainer.HeightRequest = 42;
        ImageContainer.WidthRequest = 42;

        ContentGrid.Children.Add(ImageContainer);

        ContentContainer = new ContentView
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            HorizontalOptions = LayoutOptions.FillAndExpand,
        };
        Grid.SetColumn(ContentContainer, 1);

        TextContainer = new Label
        {
            TextColor = Color.White,
            VerticalOptions = LayoutOptions.Center,
            HorizontalOptions = LayoutOptions.FillAndExpand,
        };
        ContentContainer.Content = TextContainer;

        ContentGrid.Children.Add(ContentContainer);

        base.Content = ContentGrid;

        this.Image.Source = "Image_Unchecked.png";
        this.BackgroundColor = Color.Transparent;
    }

    public static BindableProperty CheckedProperty = BindableProperty.Create(
        propertyName: "Checked",
        returnType: typeof(Boolean?),
        declaringType: typeof(Checkbox),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: CheckedValueChanged);

    public static BindableProperty TextProperty = BindableProperty.Create(
        propertyName: "Text",
        returnType: typeof(String),
        declaringType: typeof(Checkbox),
        defaultValue: null,
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: TextValueChanged);

    public Boolean? Checked
    {
        get
        {
            if (GetValue(CheckedProperty) == null)
                return null;
            return (Boolean)GetValue(CheckedProperty);
        }
        set
        {
            SetValue(CheckedProperty, value);
            OnPropertyChanged();
            RaiseCheckedChanged();
        }
    }

    private static void CheckedValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        if (newValue != null && (Boolean)newValue == true)
            ((Checkbox)bindable).Image.Source = "Image_Checked.png";
        else
            ((Checkbox)bindable).Image.Source = "Image_Unchecked.png";
    }

    public event EventHandler CheckedChanged;
    private void RaiseCheckedChanged()
    {
        if (CheckedChanged != null)
            CheckedChanged(this, EventArgs.Empty);
    }

    private Boolean _IsEnabled = true;
    public Boolean IsEnabled
    {
        get { return _IsEnabled; }
        set
        {
            _IsEnabled = value;
            OnPropertyChanged();
            this.Opacity = value ? 1 : .5;
            base.IsEnabled = value;
        }
    }

    public event EventHandler Clicked;
    private void TapGestureOnTapped(object sender, EventArgs eventArgs)
    {
        if (IsEnabled)
        {
            Checked = !Checked;
            if (Clicked != null)
                Clicked(this, new EventArgs());
        }
    }

    private static void TextValueChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ((Checkbox)bindable).TextContainer.Text = (String)newValue;
    }

    public event EventHandler TextChanged;
    private void RaiseTextChanged()
    {
        if (TextChanged != null)
            TextChanged(this, EventArgs.Empty);
    }

    public Image Image
    {
        get { return ImageContainer; }
        set { ImageContainer = value; }
    }

    public String Text
    {
        get { return (String)GetValue(TextProperty); }
        set
        {
            SetValue(TextProperty, value);
            OnPropertyChanged();
            RaiseTextChanged();
        }
    }

}