我有几个属性可以毫无问题地从视图模型更新视图。但是,当我尝试显示默认情况下处于隐藏状态的按钮时,一旦设置了某个属性,它将拒绝这样做。
App.xaml
<Application.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</Application.Resources>
GameView.xaml
<StackPanel Orientation="Horizontal">
<Button Content="Next Round" FontSize="24" Width="165" Margin="5" Height="80" Click="NextRoundButton_Click" Name="NextRound" Visibility="{Binding IsVisible, Converter={StaticResource BoolToVis}, FallbackValue=Hidden}" />
</StackPanel>
GameViewModel.cs
private bool _isVisibile;
public bool IsVisibile
{
get => _isVisibile;
set
{
_isVisibile = value;
OnPropertyChanged(nameof(IsVisibile));
}
}
// Farther down in the code during checking of win conditions
public void CheckGameWinCondition()
{
if (_dealer.CardTotal > 21)
{
_gameBoard.currentGameState = GameBoard.GameState.RoundOver;
_messages = "Dealer Bust";
_player.TotalWinnings = _player.TotalBet * 2;
_player.BankRoll += _player.TotalWinnings;
}
else if (_dealer.CardTotal == 21)
{
_gameBoard.currentGameState = GameBoard.GameState.RoundOver;
_messages = "Dealer BlackJack";
}
else if (_player.CardTotal > _dealer.CardTotal)
{
_gameBoard.currentGameState = GameBoard.GameState.RoundOver;
_messages = "Player Won";
_player.TotalWinnings = _player.TotalBet * 2;
_player.BankRoll += _player.TotalWinnings;
}
else if (_player.CardTotal < _dealer.CardTotal)
{
_gameBoard.currentGameState = GameBoard.GameState.RoundOver;
_messages = "Dealer Won";
}
else if (_player.CardTotal == _dealer.CardTotal)
{
_gameBoard.currentGameState = GameBoard.GameState.RoundOver;
_messages = "Draw";
_player.TotalWinnings = _player.TotalBet;
_player.BankRoll += _player.TotalWinnings;
}
else
{
_messages = "Error";
OnPropertyChanged(nameof(Messages));
}
_isVisibile = _gameBoard.Visible();
OnPropertyChanged(nameof(IsVisibile));
OnPropertyChanged(nameof(Dealer));
OnPropertyChanged(nameof(Player));
OnPropertyChanged(nameof(Messages));
}
这里的else
语句错误只是存根,而不是最终代码。
GameBoard.cs
public bool Visible()
{
if (currentGameState == GameState.RoundOver)
{
return true;
}
else
{
return false;
}
}
我有从我的GameViewModel
类继承的ObservableObject
。这对于我的所有其他绑定都很好,包括在整个UI中切换其他按钮上的IsEnabled
。就像我所有其他按钮和事件一样,它已经被编码,因此应该可以使用。
调试显示出_isVisible
的值已设置为true
,因为我在调用currentGameState
类中的GameBoard.GameState.RoundOver
方法以返回Visibility()
或[ C0]。
它应该进行转换,但不是。我从字面上看了关于此问题的近100条帖子。我已经尝试了遇到的所有内容,尽管GameBoard
正在按需触发,但没有任何更新。
使用按钮命令不是一种选择,因为这是我为上课而开发的游戏,并且这是我尝试在自己身上添加的一项额外功能。因此,这不是功课,而是游戏正在进行中。我只想隐藏“新回合”按钮,直到回合结束,然后出现它,以便用户可以单击它并开始下一只手。我试过将转换器放在true
下的false
中,但仍然无法正常工作。
我们的老师特别希望我们在单击按钮到OnPropertyChanged()
时从后面的代码中调用方法,而不是执行命令,以免在学习WPF时使事情变得更复杂。因此,为什么我不希望使用命令,也不想为该项目在这种情况下它们会有所帮助。
我的完整代码可以在GameView.xaml
上看到。
对于它的价值,我发现使用Window.Resources
对象比将ViewModel
属性绑定到按钮的GitHub或ICommand
属性要可靠得多。我几乎不再直接绑定Observable
或Visibility
属性。
您将需要IsEnabled
来实现命令:
IsEnabled
在您的Visibility
中,放置此端点:
this class
然后像这样钩上您的按钮:
/// <summary>
/// Josh Smith's implementation of RelayCommand. See https://gist.github.com/schuster-rainer/2648922
/// </summary>
public class RelayCommand : ICommand
{
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute) : this(execute, null) { }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute ?? throw new ArgumentNullException("execute");
_canExecute = canExecute;
}
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
}
GameViewModel.cs
对象旨在绑定到按钮的private ICommand _nextRoundCommand;
public ICommand NextRoundCommand
{
get
{
if (_nextRoundCommand== null)
_nextRoundCommand= new RelayCommand(x => NextRound(), y => IsVisibile);
return _nextRoundCommand;
}
}
public void NextRound()
{
// Implementation goes here.
}
属性。要使按钮在<Button
Name="NextRound"
Width="165"
Height="80"
Margin="5"
Command="{Binding NextRoundCommand}"
Content="Next Round"
FontSize="24"/>
属性为false时消失而不是禁用,可以向其中添加Command
:
IsEnabled
因此,正如评论中所提到的,我在绑定路径中的愚蠢错别字是因为缺少i而造成的。将其设置为IsVisible而不是IsVisibile。哭泣,生活和学习。很抱歉在这种愚蠢的错误上浪费时间,但是非常感谢您的反馈和评论。