如何让程序等到点击按钮?

How to make a program wait until a button is clicked?

提问人:Jérémie Normand 提问时间:12/13/2022 更新时间:12/16/2022 访问量:124

问:

我想知道如何让我的程序等到按下某个按钮。

为了说明我的问题,我制作了一个虚拟的 WPF 游戏,用户可以掷两个骰子,只要他没有得到双倍。游戏的目标是拥有最高的掷骰数。

我有以下“骰子”类:

class Dice
{
    TextBlock diceTextBlock;

    const int minNumber = 1;
    const int maxNumber = 6;

    int number;

    public int Number
    {
        get { return number; }
        set
        {
            number = value;
            diceTextBlock.Text = number.ToString();
        }
    }

    public Dice(TextBlock diceTextBlock)
    {
        this.diceTextBlock = diceTextBlock;
        Number = minNumber;
    }

    public void Roll()
    {
        Number = new Random().Next(minNumber, maxNumber + 1);
    }
}

我还有以下“GameWindow”类:

public partial class GameWindow : Window
{
    Dice dice1;
    Dice dice2;

    int rollCount;

    public GameWindow()
    {
        InitializeComponent();

        dice1 = new Dice(Dice1TextBlock);
        dice2 = new Dice(Dice2TextBlock);

        rollCount = 0;

        Play();
    }

    private void RollButton_Click(object sender, RoutedEventArgs e)
    {
        dice1.Roll();
        dice2.Roll();
        rollCount++;
    }

    private void Play()
    {
        do
        {
            //  Wait for the user to press the 'RollButton'
        }
        while (dice1.Number != dice2.Number);
    }
}

如何让我的程序等待用户在“Play()”方法中按下“RollButton”?

我试图学习事件和异步编程。但是,作为初学者,我很难理解这些概念。另外,我不确定这些是否有助于解决我的问题。

C# WPF 事件

评论

3赞 Tarazed 12/13/2022
我会考虑一种根本不涉及 do-while 循环的策略。取而代之的是,每次运行掷骰子按钮时,请检查您的退出条件,并执行与游戏结束相关的任何任务,前提是您的骰子相等。do-while 设计的问题是 Play 在构造函数中运行,这意味着窗口永远不会完成构造,用户也永远不会看到它。它只是被挂在一个无限循环中。
1赞 Jeroen van Langen 12/13/2022
提示:尽量不要将实例传递给类。下次您想重用该类时,将结果放在 .在类中使用该属性。调用方法不是问题。Dice1TextBlockDiceDiceLabelNumberGameWindowUpdateTextBlock(TextBlock tb, newValue);
1赞 Jeroen van Langen 12/13/2022
while 循环的问题在于,它阻塞了 UI 线程,因为它在你的 while 循环中很笨拙。

答:

0赞 Oleg_B 12/13/2022 #1

为了让您理解它,您需要删除 GameWindow 内部。因此,您需要在括号内添加到末尾。 这应该比异步编程更容易,特别是如果你只想做一个这样的简单程序。 此外,do while 循环什么都不做,只需创建一个 bool 方法,检查骰子 1 和 2 是否具有相同的数字。如果它们具有相同的数字,则可以返回 true 以结束游戏,如果没有匹配的数字,则返回 false。 在方法中,您可以检查两个数字是否匹配。如果这样做,则会显示两个数字匹配的消息以及尝试次数Play();Play();RollButton_Click(...)RollButton_Click(...)

0赞 mm8 12/16/2022 #2

您可以使用 a 异步等待:SemaphoreSlim

public partial class GameWindow : Window, IDisposable
{
    Dice dice1;
    Dice dice2;

    int rollCount;

    SemaphoreSlim semaphore = new SemaphoreSlim(0, 1);

    public GameWindow()
    {
        InitializeComponent();

        dice1 = new Dice(Dice1TextBlock);
        dice2 = new Dice(Dice2TextBlock);

        rollCount = 0;

        Loaded += async (s,e) => await PlayAsync();
    }

    private void RollButton_Click(object sender, RoutedEventArgs e)
    {
        dice1.Roll();
        dice2.Roll();
        rollCount++;
        semaphore.Release();
    }

    private async Task PlayAsync()
    {
        //  Wait for the user to press the 'RollButton'
        do
        {
            await semaphore.WaitAsync();
        }
        while (dice1.Number != dice2.Number);

        MessageBox.Show("Yes!");
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        semaphore.Dispose();
    }

    public void Dispose()
    {
        semaphore.Dispose();
    }
}