Skip to content

Instantly share code, notes, and snippets.

@fedemkr
Created October 8, 2018 18:13
Show Gist options
  • Save fedemkr/e883b6a1ad140bc6ca4cd6e49dbc867f to your computer and use it in GitHub Desktop.
Save fedemkr/e883b6a1ad140bc6ca4cd6e49dbc867f to your computer and use it in GitHub Desktop.
Xamarin forms behavior so any Image can act as a checkbox with two states which images can be set.
using Xamarin.Forms;
namespace MyNamespace.Forms.UI.Behaviors
{
public class ImageAsCheckboxBehavior : Behavior<Image>
{
// Members
private TapGestureRecognizer tapGestureRecognizer;
// Bindable properties
public static readonly BindableProperty CheckedImageSourceProperty = BindableProperty.CreateAttached("CheckedImageSource", typeof(ImageSource), typeof(ImageAsCheckboxBehavior), default(ImageSource), propertyChanged: OnCheckedImageSourceChanged);
public static readonly BindableProperty UncheckedImageSourceProperty = BindableProperty.CreateAttached("UncheckedImageSource", typeof(ImageSource), typeof(ImageAsCheckboxBehavior), default(ImageSource), propertyChanged: OnUncheckedImageSourceChanged);
public static readonly BindableProperty IsSelectedProperty = BindableProperty.CreateAttached("IsSelected", typeof(bool), typeof(ImageAsCheckboxBehavior), false, propertyChanged: OnIsSelectedChanged, defaultBindingMode: BindingMode.TwoWay);
// Accessors
[TypeConverter(typeof(ImageSourceConverter))]
public static ImageSource GetCheckedImageSource(BindableObject view)
{
return (ImageSource)view.GetValue(CheckedImageSourceProperty);
}
public static void SetCheckedImageSource(BindableObject view, ImageSource value)
{
view.SetValue(CheckedImageSourceProperty, value);
}
[TypeConverter(typeof(ImageSourceConverter))]
public static ImageSource GetUncheckedImageSource(BindableObject view)
{
return (ImageSource)view.GetValue(UncheckedImageSourceProperty);
}
public static void SetUncheckedImageSource(BindableObject view, ImageSource value)
{
view.SetValue(UncheckedImageSourceProperty, value);
}
public static bool GetIsSelected(BindableObject view)
{
return (bool)view.GetValue(IsSelectedProperty);
}
public static void SetIsSelected(BindableObject view, bool value)
{
view.SetValue(IsSelectedProperty, value);
}
// On property changed
private static void OnCheckedImageSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var image = bindable as Image;
if (image == null)
return;
if (GetIsSelected(bindable))
image.Source = (ImageSource)newValue;
}
private static void OnUncheckedImageSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var image = bindable as Image;
if (image == null)
return;
if (!GetIsSelected(bindable))
image.Source = (ImageSource)newValue;
}
private static void OnIsSelectedChanged(BindableObject bindable, object oldValue, object newValue)
{
var image = bindable as Image;
if (image == null)
return;
image.Source = (bool)newValue ? GetCheckedImageSource(image) : GetUncheckedImageSource(image);
}
// Methods
protected override void OnAttachedTo(Image bindable)
{
this.tapGestureRecognizer = new TapGestureRecognizer();
this.tapGestureRecognizer.Tapped += this.TapGestureRecognizer_Tapped;
bindable.GestureRecognizers.Add(this.tapGestureRecognizer);
base.OnAttachedTo(bindable);
bindable.Source = GetUncheckedImageSource(bindable);
}
protected override void OnDetachingFrom(Image bindable)
{
this.tapGestureRecognizer.Tapped -= this.TapGestureRecognizer_Tapped;
bindable.GestureRecognizers.Clear();
base.OnDetachingFrom(bindable);
}
private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e)
{
SetIsSelected((BindableObject)sender, !GetIsSelected((BindableObject)sender));
}
}
}
@fedemkr
Copy link
Author

fedemkr commented Oct 8, 2018

E.g.:

<Image
    WidthRequest="30"
    HeightRequest="30"
    behaviors:ImageAsCheckboxBehavior.CheckedImageSource="ic_checkbox_checked"
    behaviors:ImageAsCheckboxBehavior.UncheckedImageSource="ic_checkbox_unchecked"
    behaviors:ImageAsCheckboxBehavior.IsSelected="{Binding IsSelected}">
    <Image.Behaviors>
        <behaviors:ImageAsCheckboxBehavior />
    </Image.Behaviors>
</Image>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment