我正在制作游戏卡尔卡松,而且我正在使用MVVM。所以我有一个窗口(ApplicationView)和几个UserControls(每个视图)。该窗口包含viewModels和Datacontext中的视图。在这个窗口中,我使用ContentControl在正确的时间显示正确的视图(内容数据绑定到窗口的viewModel中的prop),视图中的这个更改在每个viewModel中完成。因此,例如从loginview到menuview,我使用一个带有命令Datacontext.changePage(位于ApplicationViewModel中)的按钮,然后将下一个viewmodel绑定到commandparameter。
这适用于所有不同的视图但是对于登录视图我首先需要检查用户名和密码,所以我写了一个不需要任何参数的新命令而不是Datacontext.changePage,它只运行控制密码和用户名的方法(在同一视图模型中都将数据绑定到道具)。这一切都运行正常,所以在我运行changePage命令(通过单件设计模式)后,它将CurrentPageViewModel更改为正确的。
问题是它没有更新我的GUI(因此它没有将viewModel更改为正确的),当我调试它时,MainWindowViewModel中的数据转换prop的propertychanged为null。所以这意味着它没有识别出属性的任何变化,但我确实改变了道具,所以我不知道这里的问题是什么!
ApplicationView xaml:
<Window.Resources>
<DataTemplate DataType="{x:Type vm:LoginViewModel}">
<vw:LoginView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MenuViewModel}">
<vw:MenuView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:NewGameViewModel}">
<vw:NewGameView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:BoardViewModel}">
<vw:BoardView />
</DataTemplate>
</Window.Resources>
<Grid Cursor="/Images/Arrow.cur">
<ContentControl Content="{Binding CurrentPageViewModel,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True,NotifyOnTargetUpdated=True,NotifyOnValidationError=True}" />
</Grid>
ApplicationViewModel
public ICommand ChangePageCommand
{
get
{
if (_changePageCommand == null)
{
_changePageCommand = new RelayCommand<IPageViewModel>(p =>ChangeViewModel(p),p => p is IPageViewModel);
}
return _changePageCommand;
}
}
public void ChangeViewModel(IPageViewModel viewModel)
{
Console.WriteLine("Changing viewmodel");
CurrentPageViewModel = viewModel;
}
public IPageViewModel CurrentPageViewModel
{
get
{
return _currentPageViewModel;
}
set
{
if (_currentPageViewModel != value)
{
_currentPageViewModel = value;
RaisePropertyChanged("CurrentPageViewModel");
}
}
}
LoginViewModel中的命令,通过Singlton design patttern更改CurrentPageViewModel:
private MenuViewModel _mvm = new MenuViewModel(null);
public MenuViewModel mvm
{
get { return _mvm;}
set {
if (value != _mvm)
{
_mvm = value;
}
}
}
private RelayCommand _loginCommand;
public ICommand LoginCommand
{
get
{
if (_loginCommand == null)
{
_loginCommand = new RelayCommand(CheckLogin);
}
return _loginCommand;
}
}
private bool _ready;
public bool ready
{
get
{
_ready = false;
if (_pswd != null && _pswd != "" && _usrn != null && _usrn != "")
{
_loggedPlayer = checkLoginDb();
if (_loggedPlayer != null)
return true;
}
return _ready;
}
}
private void CheckLogin()
{
if (ready) {
mvm = new MenuViewModel(_loggedPlayer);
RaisePropertyChanged("mvm");
ApplicationViewModel.Instance.ChangeViewModel((IPageViewModel)mvm);
}
}