Miroslav
Miroslav

Reputation: 4695

XAML style binding

I have a button, and I have a boolean property in a view-model called BooleanSwitch.

I want the text and forecolor of the button to be either:

And I want it to change dynamically when the value changes.

Sure, I can do it in the codebehind. But is there a XAML solution for this? I have tried the following:

<Style x:Key="SwitchButtonStyle" TargetType="Button">
    <Style.Triggers>
        <DataTrigger Binding="{Binding Path=BooleanSwitch}" Value="true">
            <Setter Property="Foreground" Value="Red"/>
            <Setter Property="Content" Value="ON"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=BooleanSwitch}" Value="false">
            <Setter Property="Foreground" Value="#00AA00" />
            <Setter Property="Content" Value="OFF"/>
        </DataTrigger>
    </Style.Triggers>
</Style>


<Button Click="button_Click" Style="{DynamicResource SwitchButtonStyle}" />

And the click method is just:

private void button_Click(object sender, RoutedEventArgs e)
{
    BooleanSwitch = !BooleanSwitch;
}

The code of the BooleanSwitch couldn't be simpler (.NET 4.5):

    private bool privateBooleanSwitch;
    public bool BooleanSwitch
    {
        get { return privateBooleanSwitch; }
        set
        {
            if (value == privateBooleanSwitch)
                return;

            privateBooleanSwitch= value;
            OnPropertyChanged();
        }
    }

When loaded, the triggers activate and the button is red with , but when I click the button, they no longer work...and I can see I'm probably not understanding well how DataTriggers work.

What am I doing wrong?

The button is a single purpose button but I've already found out I can't use a DataTrigger inside a specific element. I was thinking about creating another properties containing text & color and then binding those to the button properties but that just seems to me as unneccessary code tailoring, I'd rather use XAML for defining colors and texts.

Upvotes: 0

Views: 3079

Answers (1)

Miroslav
Miroslav

Reputation: 4695

Me.

Dumb.

Guess what.

public abstract class ViewModelBase
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

I actually implemented the interface INotifyPropertyChanged but forgot to mention it in the class definition.

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Instead of looking for a mistake here, I was certain there must be a mistake in my understanding of WPF triggers. Thanks to LPL.

Upvotes: 1

Related Questions