Hi,
your code works fine in my demo:
<Window x:Class="WpfApp1.Window016"
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:WpfApp016"
mc:Ignorable="d"
Title="Window016" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<Canvas>
<Button Canvas.Top="5" Canvas.Left="5" Content="Left" Command="{Binding}" CommandParameter="Left"/>
<Button Canvas.Top="5" Canvas.Left="55" Content="Right" Command="{Binding}" CommandParameter="Right"/>
<Button Canvas.Top="5" Canvas.Left="105" Content="Jump" Command="{Binding}" CommandParameter="Jump"/>
<Ellipse Height="10" Width="10" Fill="Red" Canvas.Top="{Binding PersonY}" Canvas.Left="{Binding PersonX}"/>
</Canvas>
</Window>
And ViewModel:
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace WpfApp016
{
public class ViewModel : ICommand, INotifyPropertyChanged
{
public double PersonX { get; set; } = 10;
private double _personY = 100;
public double PersonY
{
get => this._personY;
set { this._personY = value; OnPropertyChanged(); }
}
public void Execute(object parameter)
{
switch (parameter.ToString())
{
case "Left":
PersonX -= 10;
OnPropertyChanged(nameof(PersonX));
break;
case "Right":
PersonX += 10;
OnPropertyChanged(nameof(PersonX));
break;
case "Jump":
person_Jump();
break;
default:
break;
}
}
private async void person_Jump()
{
for (int i = 0; i < 10; i++) // Run a jump animation.
{
PersonY -= 10;
await Task.Delay(100);
}
for (int i = 0; i < 10; i++) // Run a fall animation.
{
PersonY += 10;
await Task.Delay(100);
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter) => true;
}
}
Result: