BooleanToVisibility转换器不适用于数据绑定

问题描述 投票:0回答:2

我有几个属性可以毫无问题地从视图模型更新视图。但是,当我尝试显示默认情况下处于隐藏状态的按钮时,一旦设置了某个属性,它将拒绝这样做。

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上看到。

c# wpf binding converters
2个回答
0
投票

对于它的价值,我发现使用Window.Resources对象比将ViewModel属性绑定到按钮的GitHubICommand属性要可靠得多。我几乎不再直接绑定ObservableVisibility属性。

您将需要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

0
投票

因此,正如评论中所提到的,我在绑定路径中的愚蠢错别字是因为缺少i而造成的。将其设置为IsVisible而不是IsVisibile。哭泣,生活和学习。很抱歉在这种愚蠢的错误上浪费时间,但是非常感谢您的反馈和评论。

© www.soinside.com 2019 - 2024. All rights reserved.