我是"播放";使用C#的WPF和MVVM(目的:也许是与学生一起演示作为WinForms的替代方案(,并为此构建了一个简单的高低游戏(猜测数字等(;游戏";除了从界面内开始新游戏的命令之外。我的笨拙解决方案是将以下内容放入代码中,这与再次调用MainWindow((基本相同:
private void Restart_Click(object sender, RoutedEventArgs e)
{
InitializeComponent();
Game = new HighLowGameViewModel();
this.DataContext = Game;
}
但我希望通过在ViewModel中使用ICommand来获得相同的效果。
VM的构造函数是:
public HighLowGameViewModel()
{
_game = new HighLowGameModel(1, 10);
MakeGuessCommand = new HighLowViewGameGuessCommand(this);
NewGameCommand = new HighLowViewGameNewGameCommand(this);
}
MakeGuessCommand实现了ICommand并运行良好,它位于自己的类中,因为我现在避免使用RelayCommand之类的东西。我在此基础上为NewGameCommand创建了一个新类:
private HighLowGameViewModel _viewModel;
public HighLowViewGameNewGameCommand(HighLowGameViewModel viewModel)
{
_viewModel = viewModel;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _viewModel.CanMakeNewGame;
}
public void Execute(object parameter)
{
_viewModel.NewGame();
}
和viewModel.NewGame(((_V(:
public void NewGame()
{
int currentMax = _game.Max;
Debug.Write("I am trying to make new game");
_game = new HighLowGameModel(1, currentMax);
}
当点击视图中的按钮时,它会运行此代码,该视图的Command设置为MakeNewCOmmand(调试。将输出写入输出窗口,并在程序加载时逐步通过HighLowGameModel的构造函数等(,但视图上没有更新游戏的任何属性。
我可能因为对设计模式的无知而错过了一些愚蠢的东西,但我希望我已经为其他人提供了足够的细节,也许可以告诉我哪里出了问题。。?如何刷新应用程序并将其返回到启动状态?
Clemens的以下评论(谢谢(:添加_game
被声明为HighLowViewModel
类中的属性,它保存游戏的数据(例如用户的猜测、计算机选择的随机值、剩余生命数等(。其中每一个都通过ViewModel中的对象绑定到View。似乎工作正常,值会在绑定到窗口上的控件时更新和显示。但是,当调用创建新游戏的命令时,它又调用模型的构造函数为游戏设置新值(起始值(:
public HighLowGameModel Game
{
get { return _game; }
set {
_game = value;
}
}
#region Constructor
public HighLowGameViewModel()
{
_game = new HighLowGameModel(1, 10);
MakeGuessCommand = new HighLowViewGameGuessCommand(this);
NewGameCommand = new HighLowViewGameNewGameCommand(this);
}
#endregion
但是,视图中的元素不会使用游戏开始时的新值进行更新。
解决方案:
ViewModel类需要实现INotifyPropertyChanged和Model(…我想我对此还有进一步的思考,即它是否应该仅是实现该接口的ViewModel,但这似乎会导致重复…?(。无论如何,在调用该类中的NewGame((时,它还需要指示OnPropertyChanged("游戏"(,如下面评论中所指出的(再次感谢(。