0
votes

Im trying to change the background color of a stack layout when a button is pressed. This is the stack layout:

        <StackLayout Padding="20" x:Name="LayoutTest" BackgroundColor="{Binding BackgroundTest}">
            <Label Text="Background" TextColor="Black" FontSize="Subtitle" FontAttributes="Bold" VerticalOptions="Center"></Label>
            <Frame CornerRadius="10" Padding="10" Margin="0, 0, 0, 10" BackgroundColor="#00A6FF">
                <RadioButton GroupName="colors"></RadioButton>
            </Frame>
            <Frame CornerRadius="10" Padding="10" Margin="0, 0, 0, 10" BackgroundColor="#13CE66">
                <RadioButton GroupName="colors" Command="{Binding ChangeBgColorGreen}"></RadioButton>
            </Frame>
            <Frame CornerRadius="10" Padding="10" Margin="0, 0, 0, 10" BackgroundColor="#FFD185">
                <RadioButton GroupName="colors"></RadioButton>
            </Frame>
            <Frame CornerRadius="10" Padding="10" Margin="0, 0, 0, 10" BackgroundColor="#F95F62">
                <RadioButton GroupName="colors"></RadioButton>
            </Frame>
            <Button Text="Change Color" Command="{Binding ChangeColor}"></Button>
        </StackLayout>

And this is my view model:

class SettingsPageViewModel : BaseViewModel
{
    public String BackgroundTest { get; set; }
    public Command ChangeColor { get; }
    public SettingsPageViewModel()
    {
        Title = "Dashboard ";

        ChangeColor = new Command(ChangeBgColor);
    }
    void ChangeBgColor()
    {
        BackgroundTest = "#F95F62";
    }
}

However, whenever the ChangeColor button is clicked, it does not seem to change the 'BackgroundTest' value. Im quite new to MVVM so am not sure how best to do this. Any help would be greatly appreciated.

2

2 Answers

0
votes

Pass a command parameter in button and remove the color binding from stack

<StackLayout Padding="20" x:Name="LayoutTest">
...
<Button Text="Change Color" Command="{Binding ChangeColor}" CommandParameter="{x:Reference LayoutTest}"></Button>

Capture the parameter in ViewModel

ChangeColor = new Command<object>(ChangeBgColor);
...
void ChangeBgColor(object obj)
{
   if(obj is StackLayout sl)
   {
       sl.BackgroundColor = Color.FromHex("#F95F62");
   }
}

This is the easy quick way, as to why your code is not working, you can try with binding mode two way

BackgroundColor="{Binding BackgroundTest,Mode="TwoWay"}"

if it still doesn't work you would need to raise this BackgroundTest property https://www.c-sharpcorner.com/article/simplifying-mvvm-inotifypropertychanged-on-xamarin-forms/

0
votes

Your SettingsPageViewModel does not raise property changed notification on the BackgroundTest property so the view that is binding to that property will never be notified that it updated.

It looks like you are using an MVVM framework since you are inheriting from BaseViewModel. Normally in these frameworks there are helper methods that you can call to raise the property changed event. Without knowing which framework you are using, I cant tell you exactly what to call here, but in Prism, it's called SetProperty and it works like this:

class SettingsPageViewModel : BaseViewModel
{
    private string _backgroundTest;
    public string BackgroundTest
    {
        get => _backgroundTest;
        set => SetProperty(ref _backgroundTest, value);
    }

    public Command ChangeColor { get; }

    public SettingsPageViewModel()
    {
        Title = "Dashboard ";

        ChangeColor = new Command(ChangeBgColor);
    }

    void ChangeBgColor()
    {
        BackgroundTest = "#F95F62";
    }
}