Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MvvmCross Checkbox bind to command android xml

Is it possible to bind android checkbox to execute a command on change? Could not find an example

like image 774
Sly Avatar asked May 13 '15 16:05

Sly


1 Answers

Standard approach would be to simply bind to property of type bool in your viewmodel and perform your logic in setter of this property. Your binding will then look like this:

local:MvxBind="Checked IsChecked"

However if you really need bind to Command, you can also bind to Click event:

local:MvxBind="Checked IsChecked; Click YourCommand;"

ViewModel:

private bool _isChecked;

public bool IsChecked
{
    get { return _isChecked; }
    set
    {
        _isChecked = value;
        RaisePropertyChanged(() => IsChecked);
    }
}

public ICommand YourCommand
{
    get
    {
        return new MvxCommand(() =>
        {
            var isChecked = IsChecked;
            //Now you can use isChecked variable
        });
    }
}

Note that you don't recieve value of the checkbox in your command parameter, so you need to bind to the bool property anyway. Another problem with this solution is that you must rely on a fact, that setter of your property would be called before your command.

If you really need to have command with bool parameter, then you can definitely do that. Awesome thing about MvvmCross framework is that you can always extend its functionality. In your case you would need to implement custom binding for CheckBox. Good starting point may be here: http://slodge.blogspot.cz/2013/06/n28-custom-bindings-n1-days-of-mvvmcross.html

Edit: To show how easy it is I gave it a try and implement simple command binding with bool parameter. (No CanExecute check). In case anyone is interested, here is the code.
Binding class:

public class CheckBoxChangedBinding
    : MvxAndroidTargetBinding
{
    private ICommand _command;

    protected CheckBox View
    {
        get { return (CheckBox) Target; }
    }

    public CheckBoxChangedBinding(CheckBox view)
        : base(view)
    {
        view.CheckedChange += CheckBoxOnCheckedChange;

    }

    private void CheckBoxOnCheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e)
    {
        if (_command == null)
            return;
        var checkBoxValue = e.IsChecked;
        _command.Execute(checkBoxValue);
    }


    protected override void SetValueImpl(object target, object value)
    {
        _command = value as ICommand;
    }

    public override MvxBindingMode DefaultMode
    {
        get { return MvxBindingMode.OneWay; }
    }

    public override Type TargetType
    {
        get { return typeof (ICommand); }
    }

    protected override void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            var view = View;
            if (view != null)
            {
                view.CheckedChange -= CheckBoxOnCheckedChange;
            }
        }
        base.Dispose(isDisposing);
    }
}

In Setup.cs:

protected override void FillTargetFactories(IMvxTargetBindingFactoryRegistry registry)
{
    base.FillTargetFactories(registry);
    registry.RegisterCustomBindingFactory<CheckBox>("CheckedChanged",
        checkBox => new CheckBoxChangedBinding(checkBox));
}

In your layout:

<CheckBox
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    local:MvxBind="CheckedChanged CheckBoxCheckedCommand" />

And finally ViewModel:

public ICommand CheckBoxCheckedCommand
{
    get
    {
        return new MvxCommand<bool>(isChecked =>
        {
            var parameter = isChecked;
        });
    }
}
like image 107
Ondřej Kunc Avatar answered Sep 25 '22 06:09

Ondřej Kunc