Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BackgroundColor Binding in MvvmCross

I am trying to change the background color of the spinner with binding BackgroundColor property in as follows, but it is having no effect.

View.axml

<mvvmcross.droid.support.v7.appcompat.widget.MvxAppCompatSpinner
    android:layout_width="115dp"
    android:layout_height="match_parent"
    android:textColor="@color/primary_text"
    local:MvxItemTemplate="@layout/single"
    local:MvxBind="ItemsSource SingleList; SelectedItem SingleSize ; BackgroundColor SingleBackgroundValueConverter(IsSingleValid)" />

Converter.cs

public class SingleBackgroundValueConverter: MvxValueConverter<bool>
{
  protected override MvxColor Convert(bool value, object parameter, CultureInfo culture)
  {
    // either white or red
    return value ? new MvxColor(255, 255, 255) : new MvxColor(255, 0, 0);
  }
}

In the following, I was able to see the alert pop up, but background color does not change at all.

ViewModel.cs

public void Save()
{
    if (!isExist)
    {
         OnExit(this, null);
    }
    else
    {
        _isSingleValid= false;
        RaisePropertyChanged(() => IsSingleValid);
        Mvx.Resolve<IUserDialogs>().Alert("It is not valid");
    }
}

private bool _isSingleValid = true;
public bool IsSingleValid
{
    get { return _isSingleValid; }
    set
    {
        _isSingleValid= value;
        RaisePropertyChanged(() => IsSingleValid);
    }
}
like image 911
casillas Avatar asked May 13 '16 22:05

casillas


2 Answers

BackgroundColor is part of the Color pluign.

The first step is to make sure you have installed it.

 Install-Package MvvmCross.Plugin.Color

And then inherit your converter from MvxColorValueConverter<T>.

public class SingleBackgroundValueConverter : MvxColorValueConverter<bool>
{
    protected override MvxColor Convert(bool value, object parameter, CultureInfo culture)
    {
        return value ? new MvxColor(255, 255, 255) : new MvxColor(255, 0, 0);
    }
}

Then you have to change your converter name in the binding, because mvvmcross naming convention strips off the ValueConverter part.

local:MvxBind="ItemsSource SingleList; SelectedItem SingleSize ; BackgroundColor SingleBackground(IsSingleValid)"
like image 71
Sven-Michael Stübe Avatar answered Nov 15 '22 11:11

Sven-Michael Stübe


The issue is there is no BackgroundColor property on a MvxAppCompatSpinner (AppCompatSpinner properties).

An alternate property that you can use is Background. However, Background requires a Android.Graphics.Drawables.Drawable and not a Android.Graphics.Color.

Therefore you will need to create a converter specifically for Android platform to return a Android.Graphics.Drawables.ColorDrawable:

public class SingleBackgroundValueConverter : MvxValueConverter<bool, ColorDrawable>
{
    protected override ColorDrawable Convert(bool value, System.Type targetType, object parameter, CultureInfo culture)
    {
        return value ? new ColorDrawable(new Color(255, 255, 255)) : new ColorDrawable(new Color(255, 0, 0));
    }
}

And then in your layout:

<mvvmcross.droid.support.v7.appcompat.widget.MvxAppCompatSpinner
  android:layout_width="115dp"
  android:layout_height="match_parent"
  android:textColor="@color/primary_text"
  local:MvxItemTemplate="@layout/single"
  local:MvxBind="ItemsSource SingleList; SelectedItem SingleSize ; Background SingleBackground(IsSingleValid)" />

Note - Using MvxValueConverter

When using the MvxValueConverter in your XML/AXML you must make sure not to include the 'ValueConverter' part of the converter name:

Error

local:MvxBind="ItemsSource SingleList; Background SingleBackgroundValueConverter(IsSingleValid)" />

You will see an error message in the ouput/logcat such as:

MvxBind:Error: 3.98 Failed to find combiner or converter for SingleBackgroundValueConverter

Working

local:MvxBind="ItemsSource SingleList; Background SingleBackground(IsSingleValid)" />

Side Note - Suggestion

In your ViewModel sample code Save() method you are assigning the _isSingleValid backing field and then manually raising the change RaisePropertyChanged(() => IsSingleValid);. You can simplify this code by just assigning the property directly IsSingleValid = false; as the set of the property will execute the RaisePropertyChanged(() => IsSingleValid);. The only time you need to assign to the backing field should be if there is some additional logic in the setter that you don't want to run when updating the property or if you don't want to raise a changed event.

like image 30
Plac3Hold3r Avatar answered Nov 15 '22 10:11

Plac3Hold3r