BackgroundColor Binding in MvvmCross
Asked Answered
H

2

5

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);
    }
}
Herring answered 13/5, 2016 at 22:53 Comment(1)
I think your method signature for your converter is copied wrong as it is missing the type parameter and should not be able to compile. It should be something like protected override MvxColor Convert(bool value, Type targetType, object parameter, CultureInfo culture)? And the converter inheritance should need the output type: MvxValueConverter<bool, MvxColor>?Blitzkrieg
K
9

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)"
Krona answered 15/5, 2016 at 16:5 Comment(0)
B
3

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.

Blitzkrieg answered 14/5, 2016 at 14:5 Comment(1)
It doesn't matter if there is a property on the Target. Mvvmcross is working with BindingTargets that can add additional "virtual" properties. In this case BackgroundColor comes from the color plugin.Hurlow

© 2022 - 2024 — McMap. All rights reserved.