Установить цвет фона LinearLayout через логическое значение

Я пытаюсь использовать MvxValueConverter для установки цвета фона LinearLayout на основе логического значения. Конвертер выглядит так:

public class BackgroundColorValueConverter : MvxValueConverter<bool, MvxColor>
{
    private static readonly MvxColor TrueBGColor = new MvxColor(0xDB, 0xFF, 0xCE);
    private static readonly MvxColor FalseBGColor = new MvxColor(0xD6, 0xF6, 0xFF);

    protected override MvxColor Convert(bool value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value ? TrueBGColor : FalseBGColor;
    }
}

в моем макете AXML у меня есть следующий код:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    local:MvxBind="BackgroundColor MyBooleanValue, Converter=BackgroundColor">
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      android:textSize="18dp"
      local:MvxBind="Text MyText" />
</LinearLayout>

Я получаю следующую ошибку:

Failed to create target binding for binding BackgroundColor for MyBooleanValue

полная трассировка ошибки выглядит следующим образом:

MvxBind:Error:  8.58 Problem seen during binding execution for binding BackgroundColor for MyBooleanValue - problem InvalidCastException: Cannot cast from source type to destination type.
03-05 14:18:46.434 I/mono-stdout(16474): MvxBind:Error:  8.58 Problem seen during binding execution for binding BackgroundColor for MyBooleanValue - problem InvalidCastException: Cannot cast from source type to destination type.
03-05 14:18:46.434 I/mono-stdout(16474):      at Cirrious.MvvmCross.Plugins.Color.Droid.BindingTargets.MvxViewBackgroundColorBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0 
      at Cirrious.MvvmCross.Plugins.Color.Droid.BindingTargets.MvxViewBackgroundColorBinding.SetValueImpl (System.Object target, System.Object value) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
03-05 14:18:46.434 I/mono-stdout(16474):   at Cirrious.MvvmCross.Binding.Bindings.Target.MvxConvertingTargetBinding.SetValue (System.Object value) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource (System.Object value) [0x00000] in <filename unknown>:0 

Итак, я честно не уверен, куда идти отсюда. Возможно ли то, что я пытаюсь сделать? Я использую правильный MvvmCross конвертер? Любые указатели будут высоко оценены.


обновление:

изменение преобразователя на:

public class BackgroundColorValueConverter : MvxColorValueConverter
{
    private static readonly MvxColor TrueBGColor = new MvxColor(0xDB, 0xFF, 0xCE);
    private static readonly MvxColor FalseBGColor = new MvxColor(0xD6, 0xF6, 0xFF);

    protected override MvxColor Convert(object value, object parameter, System.Globalization.CultureInfo culture)
    {
        return (bool)value ? TrueBGColor : FalseBGColor;
    }
}

... решил мою проблему. У меня тоже было TextColor MyBooleanValue, Converter=TextColor на LinearLayout, которые функционируют как BackgroundColorValueConverter, и я получал ту же ошибку о неспособности создать целевые привязки.

как только я изменил свой AXML на чтение:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    local:MvxBind="BackgroundColor MyBooleanValue, Converter=BackgroundColor">
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      android:textSize="18dp"
      local:MvxBind="Text MyText; TextColor MyBooleanValue, Converter=TextColor" />
</LinearLayout>

... все работало по плану. Для всех, кто наткнуться на это в будущем: не пытайтесь привязать TextColor на LinearLayout, потому что он не работает!

3 ответов


есть рабочий образец BackgroundColor привязка в https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/ValueConversion/ValueConversion.UI.Droid/Resources/Layout/View_Colors.axml

это использует привязку BackgroundColor от https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Color/Cirrious.MvvmCross.Plugins.Color.Droid/BindingTargets/MvxViewBackgroundColorBinding.cs

этот образец работает для тебя?

если да, можете ли вы определить разницу между этим образцом и тем, который вы используете? Это какая-то проблема с цветным плагином? (Это загружается в ваш проект UI?) Это проблема с LinearLayout против TextView? Есть ли еще трассировка ошибок, которую вы можете предоставить? Одна строка трассировки, которую вы предоставили, создается на https://github.com/MvvmCross/MvvmCross/blob/1ec7bc5f0307595c7ae11f56727dd0e9d2a2262f/Cirrious/Cirrious.MvvmCross.Binding/Bindings/MvxFullBinding.cs#L139- но обычно перед этой линией есть другой след.

если нет, то это беспокоит, так как это означает, что это общая ошибка...


обновление: (после получения дополнительной информации предоставленных)

Я думаю, что проблема в вашем ValueConverter-для работы с Android, ваш ValueConverter должен в конечном итоге с родным типом-не независимым от платформы MvxColor. Ошибка, которую вы видите, является недопустимым исключением приведения-потому что привязка пытается привести ваш MvxColor до Android.Graphics.Color in https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Color/Cirrious.MvvmCross.Plugins.Color.Droid/BindingTargets/MvxViewBackgroundColorBinding.cs#L25

чтобы преобразовать в родной, вы можете использовать MvxColorValueConverter базовый класс - см. https://github.com/MvvmCross/MvvmCross/blob/v3.1/Plugins/Cirrious/Color/Cirrious.MvvmCross.Plugins.Color/MvxColorValueConverter.cs

одним из примеров этого является https://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/ValueConversion/ValueConversion.Core/Converters/Converters.cs#L35

public class ContrastColorConverter : MvxColorValueConverter
{
    protected override MvxColor Convert(object value, object parameter, CultureInfo culture)
    {
        var input = (MvxColor) value;
        var brightnessToUse = SimpleContrast(input.R, input.G, input.B);
        return new MvxColor(brightnessToUse, brightnessToUse, brightnessToUse);
    }

    private static int SimpleContrast(params int[] value)
    {
        // this is only a very simple contrast method
        // for more advanced methods you need to look at HSV-type approaches

        int max = 0;
        foreach (var v in value)
        {
            if (v > max)
                max = v;
        }

        return 255 - max;
    }
}

есть некоторые документы о преобразователях цвета в https://github.com/MvvmCross/MvvmCross/wiki/Value-Converters#wiki-the-mvx-color-valueconverters


вы возвращаете логическое значение в своем методе, где он ожидает объект MvxColor.

    protected override MvxColor Convert(object value, object parameter, System.Globalization.CultureInfo culture)
{
    (bool)value ? return TrueBGColor : return FalseBGColor;
}

столкнулся с той же ошибкой о "не удалось создать целевую привязку ...", просто переместил конвертер из папки под проектом core-PCL в новую папку под проектом Droid сделал трюк для меня:)