Set ContentPage Background Color via Xaml & Converter

Hi,

I have a simple contentpage where I would like to change the background color based on a boolean value (false => background color red, true => green).

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:converters="clr-namespace:TopUpApp.Converters;assembly=FortytwoTech.Ecospace.Services.Clients.TopUpApp"
             x:Class="TopUpApp.Views.ResultView"
             Padding="10">
  <ContentPage.Resources>
    <ResourceDictionary>
      <Color x:Key="failedColor">Red</Color>
      <Color x:Key="successColor">#50E3AC</Color>
      <converters:StatusBackgroundConverter TrueValue="{StaticResource failedColor}" FalseValue="{StaticResource successColor}" x:Key="StatusBackgroundConverter"/>
    </ResourceDictionary>
  </ContentPage.Resources>
  <ContentPage.BackgroundColor>
    <Color Accent="{Binding IsSuccessful, Converter={StaticResource StatusBackgroundConverter}}"/>
  </ContentPage.BackgroundColor>
</ContentPage>

and my converter

    public class StatusBackgroundConverter : IValueConverter
    {
        public Color TrueValue { get; set; }
        public Color FalseValue { get; set; }

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var castedValue = bool.Parse(value.ToString());
            return (castedValue ? TrueValue : FalseValue);

        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

The error that is being thrown is: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> Xamarin.Forms.Xaml.XamlParseException: Position 18:12. Cannot assign property "Accent": type mismatch between "Xamarin.Forms.Binding" and "Xamarin.Forms.Color"

Apparently it doesn't work as I thouught it would be, I tried the SolidBrushColor (wpf) but that is not available.

Any suggestions how I would do this?

tnx!

Answers

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @MichelTol - The reason is the Accent property is not bindable. I am not sure if they are any bindable properties off the top of my head, but what I would recommend is create a Base Page that you inherit from. Create a bindable property in there that sets the background color, then bind to that. I know it seems like a bit of work but its the only way I can currently think of doing it.

  • michelTolmichelTol USMember ✭✭
    edited November 2015

    @AdamP thanks for replying. But I am not sure if I understand your answer.
    Could you maybe help me with a code sample?

    Update:
    I bound my color to the Accent because that was the only property available (at least that is what autocomplete told me).

  • AdamPAdamP AUUniversity ✭✭✭✭✭

    @michelTol - first off if you create a base page something called BasePage (of type ContentPage).

    Then in your current pages, in the code behind make it inherit BasePage, in the xaml you need to do something like

    <local:BasePage xmlns="clr-namespace:Mobile.Views"

    With Mobile.Views being the namespace that BasePage is in.

    In creating a Bindable Property, here is a sample I just copied from elsewhere in the forums. When the Changed event is raised, that is where you set the color in the background.

         public static readonly BindableProperty PortfolioHeaderProperty = BindableProperty.Create<PortfolioHeaderView, HeaderModel>(p => p.HeaderInfo, default(HeaderModel), BindingMode.OneWay, null, OnHeaderInfoChanged);
    
            private static void OnHeaderInfoChanged(BindableObject bindable, HeaderModel oldValue, HeaderModel newValue)
            {
                var source = bindable as PortfolioHeaderView;
                // Call source NotifyPropertyChanged or whatever you need with oldValue and newValue when changed
            }
    
    public PortfolioHeader Header
    { 
        get { return (PortfolioHeader) GetValue(HeaderProperty); }
        set { SetValue(HeaderProperty, value); }
    }
    

    Then you can Bind to this property. As you can see Bindable properties need to be setup in a certain way. If the property isn't bindable (like Accent currently isn't) then you need to wrap a Bindable property around it.

Sign In or Register to comment.