Ela Škalič
Ela Škalič

Reputation: 1

WPF Button DataTrigger does not update content when property changes

I'm working on WPF movie database application for school project and I have a button where I want to toggle the content of a Button based on a bool property IsFavorite of SelectedFilm object. When IsFavorite is true, the button should display "Remove from Favorites". When IsFavorite is false, the button should display "Add to Favorites".

I have put a text block just to test and see if the property and binding works, and it does work fine (it changes from true to false if I click on the button)

Despite the property changing correctly the Button does not update its content.

MainWindow.xaml

<Window x:Class="MovieDatabase.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:MovieDatabase"
        Title="MovieDatabase" Height="600" Width="1100" Background="#0f1013" Foreground="white" FontFamily="Arial">

    <Window.DataContext>
       <viewModels:ViewModel/>
    </Window.DataContext>

    <!-- Button with DataTrigger -->
    <StackPanel Orientation="Horizontal" Margin="0,10" DataContext="{Binding SelectedFilm}">
        <Button x:Name="ToggleFavoriteButton" Background="Red" BorderThickness="0" Click="ToggleFavorite_Click" Foreground="White" Padding="5">
            <Button.Style>
                <Style TargetType="Button">
                    <Setter Property="Content" Value="Add to Favorites" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsFavorite}" Value="True">
                            <Setter Property="Content" Value="Remove from Favorites" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </StackPanel>

    <!-- TextBlock to test IsFavorite binding -->
    <TextBlock Text="{Binding SelectedFilm.IsFavorite}" Foreground="White" Margin="10,0,0,0" Background="red" Width="30" HorizontalAlignment="Left"/>
</Window>

MainWindow.xaml.cs

public MainWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}

private void ToggleFavorite_Click(object sender, RoutedEventArgs e)
{
    if (DataContext is ViewModel viewModel && viewModel.SelectedFilm != null)
    {
        viewModel.SelectedFilm.IsFavorite = !viewModel.SelectedFilm.IsFavorite;
    }
}

ViewModel.cs

public class ViewModel : INotifyPropertyChanged
{
    private Film _selectedFilm;
    public Film SelectedFilm
    {
        get => _selectedFilm;
        set
        {
            _selectedFilm = value;
            OnPropertyChanged(nameof(SelectedFilm));
        }
    }

    public ICommand ToggleFavoriteCommand { get; }

    public ViewModel()
    {
        ToggleFavoriteCommand = new RelayCommand(ToggleFavorite, () => SelectedFilm != null);
    }

    private void ToggleFavorite()
{
    if (SelectedFilm != null)
    {
        SelectedFilm.IsFavorite = !SelectedFilm.IsFavorite;

        OnPropertyChanged(nameof(SelectedFilm));
        OnPropertyChanged(nameof(SelectedFilm.IsFavorite));

        if (SelectedGenre == "Favorites")
        {
            FilteredFilms.Refresh();
        }
    }
}

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Film.cs

public class Film : INotifyPropertyChanged
{
    private bool _isFavorite;
    public bool IsFavorite
    {
        get => _isFavorite;
        set
        {
            if (_isFavorite != value)
            {
                _isFavorite = value;
                OnPropertyChanged(nameof(IsFavorite));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Upvotes: 0

Views: 49

Answers (1)

Ela Škalič
Ela Škalič

Reputation: 1

I managed to resolve the issue thanks to the helpful comment I received. I realized the problem was caused by setting the DataContext of the StackPanel to SelectedFilm.

After removing the DataContext="{Binding SelectedFilm}" from the StackPanel, everything started working as I wanted.

Upvotes: 0

Related Questions