Search code examples
c#xamarinxamarin.formsxamarin.androidxamarin.ios

Custom control does not update background color Xamarin Forms


I have created a custom control that i want to change color after a click. I can successfully load it, but once I run my function and want to change the color, nothing happens. When i try to do it with a regular element (button, label) it works.

Custom control (that is a Grid with a simple label inside):

public partial class CustomGrid : Grid
{
    public static readonly BindableProperty ItemProperty = BindableProperty.Create(nameof(Item), typeof(Item), typeof(CustomGrid), propertyChanged: ItemChanged);
    public static readonly BindableProperty CustomColorProperty = BindableProperty.Create(nameof(IsAnonymousSubColor), typeof(Color), typeof(CustomGrid), propertyChanged: CustomColorChanged);

    public Color CustomColor
    {
        get { return (Color)GetValue(CustomColorProperty); }
        set { SetValue(CustomColorProperty, value); }
    }

    static void CustomColorChanged (object bindable, object oldValue, object newValue)
    {
        var x = bindable as CustomGrid;

        if (x.Item != null)
        {
             x.myLabelInMyXaml.BackgroundColor = x.CustomColor;
        }
    }

    static void ItemChanged (object bindable, object oldValue, object newValue)
    {
        var x = bindable as CustomGrid;
    }

    public Item Item
    {
        get { return (Item) GetValue(ItemProperty); }
        set { SetValue(ItemProperty, value); }
    }

    public CustomGrid()
    {
        InitializeComponent();
    }
}

Here is my xaml, here i bind it to the viewmodel color code (binding works well on other elements, even if i try it inside the same stacklayout).

                <StackLayout BackgroundColor="Transparent"
                             Padding="0,10,0,0"
                                 VerticalOptions = "StartAndExpand" 
                                BindableLayout.ItemsSource="{Binding newsService.FeedList}">
                    <BindableLayout.ItemTemplate>
                        <DataTemplate>
                            <StackLayout>

                                <controls:CustomGrid Item ="{Binding .}"
                                               CustomColor = "{Binding BindingContext.CustomColorViewModel, Source={x:Reference ParentView}}" />

                            </StackLayout>
                        </DataTemplate>
                    </BindableLayout.ItemTemplate>
                </StackLayout>

ViewModel:

    private Color _CustomColorViewModel;
    public Color CustomColorViewModel
    {
        get { return _CustomColorViewModel; }
        set
        {
            _CustomColorViewModel = value;
            RaisePropertyChanged("CustomColorViewModel");
        }
    }

And i change it after loading it:

public void ChangeColor ()
{
    CustomColorViewModel = Color.Red;
}

XAML of custom control:

  <?xml version="1.0" encoding="UTF-8"?>
  <Grid xmlns="http://xamarin.com/schemas/2014/forms"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:controls="clr-namespace:Neutral.Controls"
         xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
         xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
         xmlns:yummy="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView"
         x:Name="ParentView"
         x:Class="Project.Controls.CustomGrid">


         <Label x:Name = "myLabelInMyXaml" BackgroundColor = "{Binding CustomColorViewModel}"/>


 </Grid>

But the custom control background color does not change. It works when i initially load, but not when i try to update it. Note that i have no issue with other elements, only this custom control.

Not sure why it does not update the color.


Solution

  • I notice you used CustomColor property in stacklayout, but you add the IsAnonymousSubColor property in your CustomColor background code.

    I change your CustomColor background code like following format(Just test function to change the color).

      [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class CustomGrid : Grid
        {
    
            public static readonly BindableProperty CustomColorProperty = BindableProperty.Create(nameof(CustomColor), typeof(Color), typeof(CustomGrid), propertyChanged: CustomColorChanged);
    
            public Color CustomColor
            {
                get { return (Color)GetValue(CustomColorProperty); }
                set { SetValue(CustomColorProperty, value); }
            }
    
            static void CustomColorChanged(object bindable, object oldValue, object newValue)
            {
                var x = bindable as CustomGrid;
                x.myLabelInMyXaml.BackgroundColor = x.CustomColor;
    
            }
    
    
    
            public CustomGrid()
            {
                InitializeComponent();
            }
        }
    

    Here is running GIF.

    enter image description here