Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relay command in Wpf

Tags:

c#

mvvm

wpf

I'm new to c# and trying to understand how commands work in mvvm architecture. What I need to do is that updating some info when I click a button. I think I implemented the relay class fine but there is no update at all.

RelayCommand.cs

public class RelayCommand : ICommand
{
    private Action<object> execute;
    private Func<object, bool> canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }
}

MovieViewModel.cs

class MovieViewModel : INotifyPropertyChanged
{
    Movie _movie;

    private ICommand _updateCommand;
    public event PropertyChangedEventHandler PropertyChanged;

    public MovieViewModel()
    {
        _movie = new Movie
        {
            Title = "Unknown",
            Genre = "Unknown",
            Price = 11.0,
            Score = 0
        };
    }

    public Movie Movie
    {
        get
        {
            return _movie;
        }
        set
        {
            _movie = value;
        }
    }

    public string Title
    {
        get
        {
            return Movie.Title;
        }
        set
        {
            Movie.Title = value;
            RaisePropertyChanged("Title");
        }
    }

    public string Genre
    {
        get
        {
            return Movie.Genre;
        }
        set
        {
            Movie.Genre = value;
            RaisePropertyChanged("Genre");
        }
    }

    public double Price
    {
        get
        {
            return Movie.Price;
        }
        set
        {
            Movie.Price = value;
            RaisePropertyChanged("Price");
        }
    }

    public double Score
    {
        get
        {
            return Movie.Score;
        }
        set
        {
            Movie.Score = value;
            RaisePropertyChanged("Score");
        }
    }

    private void RaisePropertyChanged(string name)
    {
      PropertyChanged(this, new PropertyChangedEventArgs(name));
    }

    public ICommand UpdateCommand
    {
        get
        {
            if (_updateCommand == null)
            {
                _updateCommand = new RelayCommand(p => { updateMovie("ASD", "ZXC", 11.90, 0); }, p => true);
            }
            return _updateCommand;
        }
        set
        {
            _updateCommand = value;
        }
    }

    public Movie updateMovie(string title, string genre, double price, double score)
    {
        _movie.Title = title;
        _movie.Genre = genre;
        _movie.Price = price;
        _movie.Score = score;

        return _movie;
    }
}

Button command binding

<Button x:Name="updateBtn" Content="Update" Grid.Column="1" Grid.Row="5" Width="75" Height="30" Command="{Binding UpdateCommand}"/>
like image 828
Miral Avatar asked Oct 19 '25 00:10

Miral


1 Answers

Try giving

RaisePropertyChanged("Movie"); 

Thanks @Maverik has given the reason statement too. You're not raising PropertyChanged event since you bypass the property and access the underlying fields directly. You should use the VM like it's meant to.

The access going through VM to model applies to you just as much as it applies to views and other bound clients to your VM.

like image 109
Eldho Avatar answered Oct 21 '25 12:10

Eldho