Checkbox with Xamarin

jerome.tonnjerome.tonn USMember ✭✭

Hi @all,

I have a question regarding a Windows Phone 8.1 Silverlight Project. I would like to use a checkbox in the app. Actually I found an implementation for checkbox in Xlabs, but unfortunately it seems that I am obviously not able to use it properly. When I set in xaml Checked=true then the marker will be displayed well, when checking or unchecking it again. But in default mode or when setting it to false then checking or unchecking won't display the marker in my case. In the Custom Renderer the properties are set accordingly but nothing is displayed. Does anyone have an idea or did anyone mentioned something liek this before? Any hint or advice might be helpful.

Thanks
Jérôme

Tagged:

Best Answer

Answers

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Why don't use switch control?

  • NMackayNMackay GBInsider, University mod

    Problem with switch is it looks plain nasty on Android as is difficult to style.

  • jerome.tonnjerome.tonn USMember ✭✭

    Hi,
    @NMackay, many thanks for your response, I am just giving it a try. I will come back and tell you whether it works.

    @AlessandroCaliaro , because I want a checkbox to be displayed, and not a switch.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Use an Image control with two images, one for checked and one for unchecked state??? With TapGestureRecognizer and binding???

  • NMackayNMackay GBInsider, University mod

    @AlessandroCaliaro

    That's what my control does although it's wrapped in a contentview to give it better tapgesture support and binding added for commands etc.

  • jerome.tonnjerome.tonn USMember ✭✭

    @NMackay , thanks I think this solves actually my problem. Somekind of strange that Xlabs Checkbox Control does not work for me as expected. Thank you.

  • anmaianmai USMember ✭✭

    @AlessandroCaliaro , i'm newbie xamarin. I did as you told, but if I want to display different checkbox on each different platform. How can I do?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    As you have already read in the forums, CheckBox does not exists in xamarin. You should use Switch to have a ON/OFF control. Otherwise you have to create your own control. For example here there is a checkbox control https://github.com/gruan01/XFControls

    You can also use a Image control with a boolean value binding. If the value is true, you visualize an image (flagged, for example). If your value is false, you visualize another image...

  • anmaianmai USMember ✭✭

    Tks @AlessandroCaliaro very much!!!

  • ShubhraPandeyShubhraPandey USMember ✭✭
    edited September 2017

    @NMackay said:
    @jerome.tonn

    I wrote a toggle control, I've never tried it in a Windows phone project but it might be worth trying, you just need to add a checked and unchecked image to your platform specific project.

    using System.Threading.Tasks;
    using System.Windows.Input;
    using Xamarin.Forms;
    
    namespace Foobar.CustomControls
    {
        public class ToggleButton : ContentView
        {
            public static readonly BindableProperty CommandProperty =
                BindableProperty.Create("Command", typeof(ICommand), typeof(ToggleButton), null);
    
            public static readonly BindableProperty CommandParameterProperty =
                BindableProperty.Create("CommandParameter", typeof(object), typeof(ToggleButton), null);
    
            public static readonly BindableProperty CheckedProperty =
                BindableProperty.Create("Checked", typeof(bool), typeof(ToggleButton), false, BindingMode.TwoWay);
    
            public static readonly BindableProperty AnimateProperty =
                BindableProperty.Create("Animate", typeof(bool), typeof(ToggleButton), false);
    
            public static readonly BindableProperty EnabledProperty =
                BindableProperty.Create("Enabled", typeof(bool), typeof(ToggleButton), false);
    
            public static readonly BindableProperty CheckedImageProperty =
                BindableProperty.Create("CheckedImage", typeof(ImageSource), typeof(ToggleButton), null);
    
            public static readonly BindableProperty UnCheckedImageProperty =
                BindableProperty.Create("UnCheckedImage", typeof(ImageSource), typeof(ToggleButton), null);
    
            private ICommand _toggleCommand;
            private Image _toggleImage;
    
            public ToggleButton()
            {
                Initialize();
            }
    
            public ICommand Command
            {
                get { return (ICommand)GetValue(CommandProperty); }
                set { SetValue(CommandProperty, value); }
            }
    
            public object CommandParameter
            {
                get { return GetValue(CommandParameterProperty); }
                set { SetValue(CommandParameterProperty, value); }
            }
    
            public bool Checked
            {
                get { return (bool)GetValue(CheckedProperty); }
                set { SetValue(CheckedProperty, value); }
            }
    
            public bool Enabled
            {
                get { return (bool)GetValue(EnabledProperty); }
                set { SetValue(EnabledProperty, value); }
            }
    
            public bool Animate
            {
                get { return (bool)GetValue(AnimateProperty); }
                set { SetValue(AnimateProperty, value); }
            }
    
            public ImageSource CheckedImage
            {
                get { return (ImageSource)GetValue(CheckedImageProperty); }
                set { SetValue(CheckedImageProperty, value); }
            }
    
            public ImageSource UnCheckedImage
            {
                get { return (ImageSource)GetValue(UnCheckedImageProperty); }
                set { SetValue(UnCheckedImageProperty, value); }
            }
    
            public ICommand ToogleCommand
            {
                get
                {
                    return _toggleCommand
                           ?? (_toggleCommand = new Command(
                               () =>
                               {
                                   if (!Enabled)
                                   {
                                       return;
                                   }
    
                                   Checked = _toggleImage.Source == UnCheckedImage;
    
                                   if (Animate)
                                   {
                                       Device.BeginInvokeOnMainThread(() =>
                                       {
                                           this.ScaleTo(0.8, 50, Easing.Linear);
                                           Task.Delay(100);
                                           this.ScaleTo(1, 50, Easing.Linear);
                                       });
                                   }
                                   if (Command != null)
                                   {
                                       Command.Execute(CommandParameter);
                                   }
                               }
                               ));
                }
            }
    
            private void Initialize()
            {
                _toggleImage = new Image();
    
                Animate = true;
                GestureRecognizers.Add(new TapGestureRecognizer
                {
                    Command = ToogleCommand
                });
    
                _toggleImage.Source = UnCheckedImage;
    
                var stk = new StackLayout
                {
                    HorizontalOptions = LayoutOptions.FillAndExpand,
                    VerticalOptions = LayoutOptions.FillAndExpand
                };
                _toggleImage.Aspect = Aspect.Fill;
                _toggleImage.VerticalOptions = LayoutOptions.CenterAndExpand;
                _toggleImage.HorizontalOptions = LayoutOptions.CenterAndExpand;
                stk.Children.Add(_toggleImage);
    
                Content = stk;
            }
    
            protected override void OnParentSet()
            {
                base.OnParentSet();
                _toggleImage.Source = UnCheckedImage;
                Content = _toggleImage;
            }
    
            protected override void OnPropertyChanged(string propertyName = null)
            {
                base.OnPropertyChanged();
                if (propertyName == null) return;
                if (Equals(propertyName, "Checked"))
                {
                    _toggleImage.Source = Equals(Checked, true) ? CheckedImage : UnCheckedImage;
                }
            }
        }
    }
    

    Usage

     <custom:ToggleButton Grid.Row="0" Grid.RowSpan="3" Grid.Column="3"
                                                CheckedImage="FavChecked.png"
                                                UnCheckedImage="FavUnchecked.png"
                                                Command="{Binding Source={x:Reference OrderSearch}, Path=BindingContext.AddFavCommand}"
                                                CommandParameter="{Binding .}"
                                                Enabled="{Binding Source={x:Reference OrderSearch}, Path=BindingContext.IsFavAddEnabled}"
                                                Animate="False"
                                                Checked="{Binding .Favorite, Mode=TwoWay}"
                                                VerticalOptions="FillAndExpand"
                                                HorizontalOptions="FillAndExpand" />
    

    Might be worth a try, works fine in iOS and Android apps.

    Thanks a tonn @NMackay. It woked for me flawlessly.

  • solnJsolnJ FRMember ✭✭

    @NMackay said:
    @jerome.tonn

    I wrote a toggle control, I've never tried it in a Windows phone project but it might be worth trying, you just need to add a checked and unchecked image to your platform specific project.

    using System.Threading.Tasks;
    using System.Windows.Input;
    using Xamarin.Forms;
    
    namespace Foobar.CustomControls
    {
        public class ToggleButton : ContentView
        {
            public static readonly BindableProperty CommandProperty =
                BindableProperty.Create("Command", typeof(ICommand), typeof(ToggleButton), null);
    
            public static readonly BindableProperty CommandParameterProperty =
                BindableProperty.Create("CommandParameter", typeof(object), typeof(ToggleButton), null);
    
            public static readonly BindableProperty CheckedProperty =
                BindableProperty.Create("Checked", typeof(bool), typeof(ToggleButton), false, BindingMode.TwoWay);
    
            public static readonly BindableProperty AnimateProperty =
                BindableProperty.Create("Animate", typeof(bool), typeof(ToggleButton), false);
    
            public static readonly BindableProperty EnabledProperty =
                BindableProperty.Create("Enabled", typeof(bool), typeof(ToggleButton), false);
    
            public static readonly BindableProperty CheckedImageProperty =
                BindableProperty.Create("CheckedImage", typeof(ImageSource), typeof(ToggleButton), null);
    
            public static readonly BindableProperty UnCheckedImageProperty =
                BindableProperty.Create("UnCheckedImage", typeof(ImageSource), typeof(ToggleButton), null);
    
            private ICommand _toggleCommand;
            private Image _toggleImage;
    
            public ToggleButton()
            {
                Initialize();
            }
    
            public ICommand Command
            {
                get { return (ICommand)GetValue(CommandProperty); }
                set { SetValue(CommandProperty, value); }
            }
    
            public object CommandParameter
            {
                get { return GetValue(CommandParameterProperty); }
                set { SetValue(CommandParameterProperty, value); }
            }
    
            public bool Checked
            {
                get { return (bool)GetValue(CheckedProperty); }
                set { SetValue(CheckedProperty, value); }
            }
    
            public bool Enabled
            {
                get { return (bool)GetValue(EnabledProperty); }
                set { SetValue(EnabledProperty, value); }
            }
    
            public bool Animate
            {
                get { return (bool)GetValue(AnimateProperty); }
                set { SetValue(AnimateProperty, value); }
            }
    
            public ImageSource CheckedImage
            {
                get { return (ImageSource)GetValue(CheckedImageProperty); }
                set { SetValue(CheckedImageProperty, value); }
            }
    
            public ImageSource UnCheckedImage
            {
                get { return (ImageSource)GetValue(UnCheckedImageProperty); }
                set { SetValue(UnCheckedImageProperty, value); }
            }
    
            public ICommand ToogleCommand
            {
                get
                {
                    return _toggleCommand
                           ?? (_toggleCommand = new Command(
                               () =>
                               {
                                   if (!Enabled)
                                   {
                                       return;
                                   }
    
                                   Checked = _toggleImage.Source == UnCheckedImage;
    
                                   if (Animate)
                                   {
                                       Device.BeginInvokeOnMainThread(() =>
                                       {
                                           this.ScaleTo(0.8, 50, Easing.Linear);
                                           Task.Delay(100);
                                           this.ScaleTo(1, 50, Easing.Linear);
                                       });
                                   }
                                   if (Command != null)
                                   {
                                       Command.Execute(CommandParameter);
                                   }
                               }
                               ));
                }
            }
    
            private void Initialize()
            {
                _toggleImage = new Image();
    
                Animate = true;
                GestureRecognizers.Add(new TapGestureRecognizer
                {
                    Command = ToogleCommand
                });
    
                _toggleImage.Source = UnCheckedImage;
    
                var stk = new StackLayout
                {
                    HorizontalOptions = LayoutOptions.FillAndExpand,
                    VerticalOptions = LayoutOptions.FillAndExpand
                };
                _toggleImage.Aspect = Aspect.Fill;
                _toggleImage.VerticalOptions = LayoutOptions.CenterAndExpand;
                _toggleImage.HorizontalOptions = LayoutOptions.CenterAndExpand;
                stk.Children.Add(_toggleImage);
    
                Content = stk;
            }
    
            protected override void OnParentSet()
            {
                base.OnParentSet();
                _toggleImage.Source = UnCheckedImage;
                Content = _toggleImage;
            }
    
            protected override void OnPropertyChanged(string propertyName = null)
            {
                base.OnPropertyChanged();
                if (propertyName == null) return;
                if (Equals(propertyName, "Checked"))
                {
                    _toggleImage.Source = Equals(Checked, true) ? CheckedImage : UnCheckedImage;
                }
            }
        }
    }
    

    Usage

     <custom:ToggleButton Grid.Row="0" Grid.RowSpan="3" Grid.Column="3"
                                                CheckedImage="FavChecked.png"
                                                UnCheckedImage="FavUnchecked.png"
                                                Command="{Binding Source={x:Reference OrderSearch}, Path=BindingContext.AddFavCommand}"
                                                CommandParameter="{Binding .}"
                                                Enabled="{Binding Source={x:Reference OrderSearch}, Path=BindingContext.IsFavAddEnabled}"
                                                Animate="False"
                                                Checked="{Binding .Favorite, Mode=TwoWay}"
                                                VerticalOptions="FillAndExpand"
                                                HorizontalOptions="FillAndExpand" />
    

    Might be worth a try, works fine in iOS and Android apps.

    Hi @NMackay can your code be applied to a button in a listview? If so, how? And how to add the images in the resources?

  • NMackayNMackay GBInsider, University mod
    edited February 2018

    Well you can use it in a ViewCell is you want a list of items which checkboxes.

    I'm not sure what you mean by button.

    <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="32" />
                                    <ColumnDefinition Width="*" />
                                    <ColumnDefinition Width="40" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <Image Source="IconOrder"
                                       Grid.Column="0"
                                       Grid.Row="0"
                                       Grid.RowSpan="2" />
                                <Label Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="2"
                                       FontAttributes="None" TextColor="Black"
                                       LineBreakMode="TailTruncation"
                                       Text="{Binding OrdName}">
                                    <Label.FontSize>
                                        <OnPlatform x:TypeArguments="x:Double" iOS="14" Android="16" />
                                    </Label.FontSize>
                                </Label>
                                <Label Grid.Row="1" Grid.Column="1" VerticalOptions="Start"
                                       FontSize="12"
                                       Text="{Binding OrdId, StringFormat='ID: {0}'}"
                                       TextColor="Black" />
                                <StackLayout Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" VerticalOptions="FillAndExpand"
                                             HorizontalOptions="FillAndExpand">
                                    <custom:ToggleButton CheckedImage="CheckedOn.png" BackgroundColor="Transparent"
                                                         UnCheckedImage="CheckedOff.png" Enabled="True"
                                                         Command="{Binding Source={x:Reference OrderList}, Path=BindingContext.ToggleCommand}"
                                                         CommandParameter="{Binding .}"
                                                         Animate="True" Checked="{Binding .Favorite, Mode=TwoWay}"
                                                         VerticalOptions="CenterAndExpand" HorizontalOptions="Center" />
                                </StackLayout>
                            </Grid>
                        </ViewCell>
    

    There's various guides on working with image resources

    https://developer.xamarin.com/guides/xamarin-forms/user-interface/images/

  • solnJsolnJ FRMember ✭✭

    @NMackay first i wanted add checkbox in my list view but this is not possible and i can't use switch so i decided to use a button but if this work you will have saved my life!
    I test it and come back to you to tell you if it works.

  • solnJsolnJ FRMember ✭✭

    @NMackay it doesn't work ... I don't know what I'm doing wrong my vs don't recognize GestureRecognizers and my folder Images...
    is it possible to customize a switch so that it looks like a checkbox? it seems so simple...

  • NMackayNMackay GBInsider, University mod

    @solnJ

    PM me and I'll send you a sample.

  • SubramanyamRajuSubramanyamRaju INMember ✭✭

    You can also find CheckBox sample in Xamarin.Forms from here

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    I suppose next XF release should have checkbox

  • kjurczykkjurczyk Member ✭✭

    Hi! In the "Usage" section posted by @NMackay, one of the lines is:
    Command="{Binding Source={x:Reference OrderSearch}, Path=BindingContext.AddFavCommand}"

    What does OrderSearch mean? When I try to run this code I get an error that says the following:

    Unhandled Exception:
    Xamarin.Forms.Xaml.XamlParseExecption: Position 61:35. Can not find the object referenced by 'OrderSearch'

  • NMackayNMackay GBInsider, University mod
    edited September 2018

    @kjurczyk said:
    Hi! In the "Usage" section posted by @NMackay, one of the lines is:
    Command="{Binding Source={x:Reference OrderSearch}, Path=BindingContext.AddFavCommand}"

    What does OrderSearch mean? When I try to run this code I get an error that says the following:

    Unhandled Exception:
    Xamarin.Forms.Xaml.XamlParseExecption: Position 61:35. Can not find the object referenced by 'OrderSearch'

    That was just a sample, change OrderSearch to the name of your page as your essentially referencing the root element of the page x:Name="MyPageRoot"

    Command="{Binding Source={x:Reference MyPageRoot}, Path=BindingContext.ToggleCommand}"

  • kjurczykkjurczyk Member ✭✭

    @NMackay said:

    That was just a sample, change OrderSearch to the name of your page as your essentially referencing the root element of the page x:Name="MyPageRoot"

    Command="{Binding Source={x:Reference MyPageRoot}, Path=BindingContext.ToggleCommand}"

    Thank you! That got rid of the error!

  • ericawxwericawxw Member ✭✭

    Hi @NMackay , I tried your code but it doesn't work on my app, same issue as it does not recognize GestureRecognizers. Any help would be appreciated.

Sign In or Register to comment.