Ну, если прям на чистом WPF, без всякого упрощающего жизнь обвеса типа ReactiveUI, то как-то так.
Код вьюмодельки.
internal class MainViewModel
{
private sealed class PlayCmd(MainViewModel mainViewModel) : ICommand
{
/// <summary>
/// Можно ли вызвать команду? Влияет на доступность привязанных к команде контролов, например кнопки
/// </summary>
public bool CanExecute(object? parameter) =>
// команду Play можно вызвать только если мы ещё не начали проигрывание
!mainViewModel.isPlaying;
/// <summary>
/// Ивент, нужный чтобы уведомить об изменении значения свойства CanExecute
/// </summary>
public event EventHandler? CanExecuteChanged;
public void Execute(object? parameter)
{
// вызываем метод у вьюмодели
mainViewModel.Play();
// дёргаем событие, чтобы сообщить всем, кто привязался к команде,
// что её статус "можно исполнить" изменился
// если этого не сделать, то кнопка НЕ задизаблится (хотя CanExecute уже возвращает false)
this.OnCanExecuteChanged();
}
private void OnCanExecuteChanged() =>
this.CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
private readonly PlayCmd playCommand;
private bool isPlaying = false;
public MainViewModel()
{
this.playCommand = new(this);
}
public ICommand PlayCommand => this.playCommand;
public void Play()
{
//Player.Play();
this.isPlaying = true;
}
}
Код вьюхи.
<Window x:Class="Miramax.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Miramax"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:MainViewModel />
</Window.DataContext>
<Grid>
<Button Command="{Binding PlayCommand}">Click</Button>
</Grid>
</Window>