【问题标题】:C# WinForms: Waiting for a button press inside an infinite loopC# WinForms:在无限循环中等待按钮按下
【发布时间】:2010-11-03 13:13:30
【问题描述】:

我正在用 GUI 制作一个简单的猜数字游戏。我需要等待一个循环,等待用户在文本框中输入一个数字,然后按“确定”。如何在循环中等待事件?

注意:我不想要消息框。这是在主窗口中完成的,因此需要等待输入。

编辑:我应该更好地解释自己。我知道 GUI 中有一个循环。我想要的是方法中的 another 循环。也许有更好的方法来做到这一点。现在我考虑了一下,我可以在按钮的事件处理程序中编写代码。虽然我需要全局变量。 Whataver,我会考虑一下,但我希望我的问题现在更清楚了。

编辑 2: 抱歉,我的问题不清楚,编辑并没有多大帮助。首先,代码太大,这里就不贴了。我可能不得不发布 GUI 的屏幕截图,所以它没有多大用处。基本上,我有两个字段,“最大数量”和“允许猜测的数量”。用户输入这两个并点击“播放”。一个新面板变为可用,带有一个文本框和一个“猜测”按钮。用户输入一个猜测,程序会检查它是否正确。

第二个无限循环的目的是避免全局变量。看,每次用户点击“玩”,游戏必须生成一个新的随机数作为正确的猜测。如果一切都在一个方法内完成,那没问题。但是如果多次调用“Guess”按钮的事件处理程序,则该数字必须存储为 Form 的实例变量。当然,这没什么大不了的,但我认为数字应该是指导当前游戏的方法的属性,而不是表单的属性。

我还必须跟踪方法之外的剩余猜测次数。再说一次,这没什么大不了的。如果可以的话,我只想避免使用全局变量。

再次抱歉,我的问题不太清楚。有点累,不想写太多。如果这仍然不清楚,请不要打扰。我会想办法的。

【问题讨论】:

  • 也许你应该解释一下无限循环的目的是什么,或者发布一些代码......这样我们就可以停止假设你是新手。
  • 您总是可以创建一个 Game 类来处理跟踪所有内容。

标签: c# events infinite-loop


【解决方案1】:

是的,如果我正在等待语音事件,它可能会在函数运行时的任何事件发生,我需要在不递归调用函数的情况下处理它

【讨论】:

    【解决方案2】:

    Jason Down 的建议是明智的,创建一个新的GuessingGame 类并将其添加到您的项目中。我知道你担心“全局变量”(学校里教过每个人从不使用它,除非你绝对必须这样做),但请考虑一下你的设计规范。

    但是如果“Guess”按钮的事件处理程序被多次调用,则该数字必须存储为 Form 的实例变量。当然,这没什么大不了的,但我认为数字应该是指导当前游戏的方法的属性,而不是表单的属性。

    作为替代方案,将GuessingGame 类的实例存储在表单中。这不是全局变量!您自己说过,游戏的重点是跟踪猜测并在每次单击“播放”时生成新的数字进行猜测。如果您将游戏实例存储在表单中然后打开另一个表单(例如“帮助”或“关于”框),则游戏的实例将不可用(因此,不是全局的)。

    GuessingGame 对象看起来像:

    public class GuessingGame
    {
        private static Random _RNG = new Random();
        private bool _GameRunning;
        private bool _GameWon;
        private int _Number;
        private int _GuessesRemaining;
    
        public int GuessesRemaining
        {
            get { return _GuessesRemaining; }
        }
    
        public bool GameEnded
        {
            get { return !_GameRunning; }
        }
    
        public bool GameWon
        {
            get { return _GameWon; }
        }
    
        public GuessingGame()
        {
            _GameRunning = false;
            _GameWon = false;
        }
    
        public void StartNewGame(int numberOfGuesses, int max)
        {
            if (max <= 0)
                throw new ArgumentOutOfRangeException("max", "Must be > 0");
    
            if (max == int.MaxValue)
                _Number = _RNG.Next();
            else
                _Number = _RNG.Next(0, max + 1);
    
            _GuessesRemaining = numberOfGuesses;
            _GameRunning = true;
        }
    
        public bool MakeGuess(int guess)
        {
            if (_GameRunning)
            {
                _GuessesRemaining--;
                if (_GuessesRemaining <= 0)
                {
                    _GameRunning = false;
                    _GameWon = false;
                    return false;
                }
    
                if (guess == _Number)
                {
                    _GameWon = true;
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                throw new Exception("The game is not running. Call StartNewGame() before making a guess.");
            }
        }
    }
    

    这样,所有与游戏相关的数据都封装在类中。在表单的代码隐藏中连接事件很容易:

    GuessingGame game = new GuessingGame();
    
    private void btnPlay_Click(object sender, EventArgs e)
    {
        int numberOfGuesses = Convert.ToInt32(txtNumberOfGuesses.Text);
        int max = Convert.ToInt32(txtMax.Text);
        game.StartNewGame(numberOfGuesses, max);
    }
    
    private void btnGuess_Click(object sender, EventArgs e)
    {
        int guess = Convert.ToInt32(txtGuess.Text);
        bool correct = game.MakeGuess(guess);
    
        if (correct) 
            lblWin.Visible = true;
    
        if (game.GameEnded)
        {
            // disable guess button, show loss label
        }
    }
    

    【讨论】:

      【解决方案3】:

      正如已经指出的那样,您很可能做错了,但您可以使用它

      Application.DoEvents();

      在实际循环中处理事件

      以正确的方式做事 - 不要使用循环 - 使用编辑框输入,然后使用按钮 - 实现按钮onclick事件

      【讨论】:

        【解决方案4】:

        您可能应该寻找一本书来真正学习 Windows 编程。

        最基本的:

        1) 在某个地方的 Windows 代码深处已经存在无限循环。任何 Windows 程序都在不断循环和扫描输入。

        2) 一旦找到输入,这个循环就会触发一个事件。

        3) 如果您选择接受,您的任务是编写事件处理程序来处理这些事件。

        【讨论】:

          【解决方案5】:

          C# 自动无限循环等待事件,直到您的表单关闭。您只需要响应按钮点击事件即可。

          【讨论】:

            猜你喜欢
            • 2017-04-03
            • 2013-03-31
            • 1970-01-01
            • 1970-01-01
            • 2013-08-02
            • 2011-08-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多