使用 ICommand 更改 ViewModel 的状态
Use ICommand to change the state of the ViewModel
我想使用 ICommand 更改我的 ViewModel 的 Paddle1.Y int 值。我应该创建一个 class 实现 ICommand 接口吗?我已经做到了。但是因为它是 class,所以如果不为其创建 属性,它就无法访问我的 ViewModel 的 Paddle1 属性。出于这个原因,我更愿意在我的 ViewModel 中创建命令。此时我正在尝试将 Paddle1 作为 XAML 中的 CommandParameter 传递给 Command。我在这方面失败了,我也不确定这是编辑我的 ViewModel 状态的最干净的方法。
我能得到一个代码示例,说明我的 UpKeyPressed 命令被绑定到一个按钮或键盘向上键吗?没有 CommandParameter 会更干净,如果命令可以访问我的 ViewModel Paddle1 属性.
我的视图模型:
namespace Pong.Core.ViewModels
{
public class GamePlayViewModel
{
private readonly Paddle Paddle1;
private Paddle Paddle2;
public GamePlayViewModel()
{
Paddle1 = new Paddle();
Paddle2 = new Paddle();
UpKeyPressed();
}
public ICommand UpKeyPressed()
{
var r = new UpKeyPressed();
r.Execute(Paddle1);
return r;
}
}
public class UpKeyPressed : ICommand
{
public void Execute(object parameter)
{
var paddle = parameter as Paddle;
Debug.Assert(paddle != null, "paddle != null");
paddle.IncreaseY();
Debug.WriteLine(paddle.Y);
}
public bool CanExecute(object parameter)
{
return parameter != null;
}
public event EventHandler CanExecuteChanged;
}
}
我的 XAML 使用视图模型作为 dataContext 的页面:
<Window x:Class="Pong.Windows.Views.GamePlayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Pong.Core.ViewModels;assembly=Pong.Core"
Title="GamePlayView" Height="350" Width="525">
<Grid>
<Button CommandParameter="{Binding ElementName=Paddle1}"
Command="{StaticResource UpKeyPressed}" >
Click
</Button>
</Grid>
<Window.DataContext>
<local:GamePlayViewModel/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Command="{Binding Path=UpKeyPressed}"
Key="O"
Modifiers="Control"/>
</Window.InputBindings>
</Window>
我的解决方案的数据结构
我的修复尝试:
namespace Pong.Core.ViewModels
{
public class GamePlayViewModel
{
private readonly Paddle Paddle1;
private Paddle Paddle2;
private ICommand _doSomething;
public ICommand DoSomethingCommand
{
get
{
if (_doSomething == null)
{
_doSomething = new UpKeyPressed(Paddle1);
}
return _doSomething;
}
}
public GamePlayViewModel()
{
Paddle1 = new Paddle();
Paddle2 = new Paddle();
}
}
public class UpKeyPressed : ICommand
{
private Paddle Paddle1;
public UpKeyPressed(Paddle paddle)
{
Paddle1 = paddle;
}
public void Execute(object parameter)
{
//var paddle = parameter as Paddle;
//Debug.Assert(paddle != null, "paddle != null");
//paddle.IncreaseY();
Paddle1.IncreaseY();
//Debug.WriteLine(paddle.Y);
Debug.WriteLine(Paddle1.Y);
}
public bool CanExecute(object parameter)
{
return Paddle1 != null;
}
public event EventHandler CanExecuteChanged;
}
}
XAML 尝试(没有错误,但在按下 'O' 键后不起作用):
<Window x:Class="Pong.Windows.Views.GamePlayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:Pong.Core.ViewModels;assembly=Pong.Core"
Title="GamePlayView" Height="350" Width="525">
<Grid>
</Grid>
<Window.DataContext>
<viewModels:GamePlayViewModel/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Command="{Binding DoSomethingCommand}"
Key="O"
Modifiers="Control"/>
</Window.InputBindings>
查看了您的尝试,我们需要解决一些问题,首先您的 CanExecute
不应再涉及 parameter
:
public bool CanExecute(object parameter) {
return Paddle1 != null;
}
其次,您的 XAML 绑定是错误的,您的视图模型的 DataContext 已经在您的可视化树中运行,您只需要一个简单的绑定,其中指定了一些路径,如下所示:
<KeyBinding Command="{Binding DoSomethingCommand}"
Key="O"
Modifiers="Control"/>
我想使用 ICommand 更改我的 ViewModel 的 Paddle1.Y int 值。我应该创建一个 class 实现 ICommand 接口吗?我已经做到了。但是因为它是 class,所以如果不为其创建 属性,它就无法访问我的 ViewModel 的 Paddle1 属性。出于这个原因,我更愿意在我的 ViewModel 中创建命令。此时我正在尝试将 Paddle1 作为 XAML 中的 CommandParameter 传递给 Command。我在这方面失败了,我也不确定这是编辑我的 ViewModel 状态的最干净的方法。
我能得到一个代码示例,说明我的 UpKeyPressed 命令被绑定到一个按钮或键盘向上键吗?没有 CommandParameter 会更干净,如果命令可以访问我的 ViewModel Paddle1 属性.
我的视图模型:
namespace Pong.Core.ViewModels
{
public class GamePlayViewModel
{
private readonly Paddle Paddle1;
private Paddle Paddle2;
public GamePlayViewModel()
{
Paddle1 = new Paddle();
Paddle2 = new Paddle();
UpKeyPressed();
}
public ICommand UpKeyPressed()
{
var r = new UpKeyPressed();
r.Execute(Paddle1);
return r;
}
}
public class UpKeyPressed : ICommand
{
public void Execute(object parameter)
{
var paddle = parameter as Paddle;
Debug.Assert(paddle != null, "paddle != null");
paddle.IncreaseY();
Debug.WriteLine(paddle.Y);
}
public bool CanExecute(object parameter)
{
return parameter != null;
}
public event EventHandler CanExecuteChanged;
}
}
我的 XAML 使用视图模型作为 dataContext 的页面:
<Window x:Class="Pong.Windows.Views.GamePlayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Pong.Core.ViewModels;assembly=Pong.Core"
Title="GamePlayView" Height="350" Width="525">
<Grid>
<Button CommandParameter="{Binding ElementName=Paddle1}"
Command="{StaticResource UpKeyPressed}" >
Click
</Button>
</Grid>
<Window.DataContext>
<local:GamePlayViewModel/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Command="{Binding Path=UpKeyPressed}"
Key="O"
Modifiers="Control"/>
</Window.InputBindings>
</Window>
我的解决方案的数据结构
我的修复尝试:
namespace Pong.Core.ViewModels
{
public class GamePlayViewModel
{
private readonly Paddle Paddle1;
private Paddle Paddle2;
private ICommand _doSomething;
public ICommand DoSomethingCommand
{
get
{
if (_doSomething == null)
{
_doSomething = new UpKeyPressed(Paddle1);
}
return _doSomething;
}
}
public GamePlayViewModel()
{
Paddle1 = new Paddle();
Paddle2 = new Paddle();
}
}
public class UpKeyPressed : ICommand
{
private Paddle Paddle1;
public UpKeyPressed(Paddle paddle)
{
Paddle1 = paddle;
}
public void Execute(object parameter)
{
//var paddle = parameter as Paddle;
//Debug.Assert(paddle != null, "paddle != null");
//paddle.IncreaseY();
Paddle1.IncreaseY();
//Debug.WriteLine(paddle.Y);
Debug.WriteLine(Paddle1.Y);
}
public bool CanExecute(object parameter)
{
return Paddle1 != null;
}
public event EventHandler CanExecuteChanged;
}
}
XAML 尝试(没有错误,但在按下 'O' 键后不起作用):
<Window x:Class="Pong.Windows.Views.GamePlayView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModels="clr-namespace:Pong.Core.ViewModels;assembly=Pong.Core"
Title="GamePlayView" Height="350" Width="525">
<Grid>
</Grid>
<Window.DataContext>
<viewModels:GamePlayViewModel/>
</Window.DataContext>
<Window.InputBindings>
<KeyBinding Command="{Binding DoSomethingCommand}"
Key="O"
Modifiers="Control"/>
</Window.InputBindings>
查看了您的尝试,我们需要解决一些问题,首先您的 CanExecute
不应再涉及 parameter
:
public bool CanExecute(object parameter) {
return Paddle1 != null;
}
其次,您的 XAML 绑定是错误的,您的视图模型的 DataContext 已经在您的可视化树中运行,您只需要一个简单的绑定,其中指定了一些路径,如下所示:
<KeyBinding Command="{Binding DoSomethingCommand}"
Key="O"
Modifiers="Control"/>