【问题标题】:C# Method Wait For User ClickC#方法等待用户点击
【发布时间】:2010-12-08 13:50:53
【问题描述】:

我正在尝试编写一个循环并重复调用其他方法的方法。循环中有一个地方我需要暂停并等待用户单击 GUI 上的几个按钮之一。我以前用命令行代码完成了这个,但我不知道如何等待并检查是否有任何按钮被点击。如果有人可以帮助我,我将非常感激。下面是我想做的一个例子。

While(MoreLeftToD0){
Method1();
WaitForUserToClickButton();
If(Button1 was clicked)
    ProcessWithButton1();
else
    ProcessWithButton2(); }

编辑:我认为更多信息可能会有所帮助,也许我对此的想法不正确。我正在尝试构建一个具有 2 个玩家的简单游戏,其中 0、1 或 2 个玩家可能是机器人,而其他玩家将是人类。我想要一个具有从 Player 继承的 Human 和 Bot 类的基本 Player 类。

循环用于游戏板,我希望能够调用 CurrentPlayer.GetMove(gameBoard),对于机器人而言,它将传递游戏板并让他们决定移动。但是,如果是人,GetMove() 应该等待用户点击 GUI 上的按钮,说明他们想在板上做什么,然后相应地处理点击。

希望这会稍微澄清一下目的。如果有更好的方法来做到这一点,我很想听听建议。谢谢!

【问题讨论】:

    标签: c# winforms user-interface methods


    【解决方案1】:

    通常,您可以通过单击按钮将之前要完成的工作和之后要完成的工作分开来做到这一点。

    Part1()
    {
      DoSomething();
      btn.Enabled = true;
    }
    
    private void button1_Click(object sender, EventArgs e)
    {
      btn1.Enabled = false;
      Part2();
    }
    

    做点什么,启用你已经挂接到button1_Click事件处理程序的按钮,当用户点击按钮时,禁用它,这样他就不能再点击它了。

    【讨论】:

    • 这很好,但在我的应用程序中,我并不总是希望等待按钮单击。如果当前 Player 是人类,我需要等待点击。但是,如果他们是机器人,则无需等待按钮单击。我只需要他们处理董事会,制定并采取行动。
    • 不确定我是否理解。你能检测出它是否是机器人吗?如果是这样,在这种情况下直接调用 Part2() 即可。
    • if (IsBot) { Part2() } else { btn.Enabled = true }
    • 我能做到,我只是希望能像对待机器人和人类一样对待。无论如何,只需加载当前播放器(可以是机器人或人类)并调用 .GetMove()。如果我不能,我不能。不过,我感谢您的帮助。
    • 嗯。好吧,你可以稍微清理一下,但考虑到 Windows 消息泵的工作方式,我认为你会遇到这种情况的一些变体。如果您的逻辑发生在主 UI 线程上,您不能只是停下来等待(至少,不是没有丑陋的黑客)。如果您停止并且不将控制权返回给消息泵,您的 UI 将停止更新并看起来像崩溃了。
    【解决方案2】:

    不需要做这一切。

    您只需要在 Windows 窗体中使用事件处理程序。

    Here's 可以阅读的演练。

    例如,在 C# 中,您可以订阅事件,并在以下代码中编写您想到的任何逻辑:

    private void button1_Click(object sender, System.EventArgs e) 
    {
    // Add event-handler code here.
    }
    

    【讨论】:

      【解决方案3】:

      所以,在 WinForms 中,您已经有了一个消息循环。您处理此问题的方式是订阅按钮单击事件。下面的这篇文章可能会帮助你弄清楚一些事情:

      https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-1050284.html

      如果这不是你的意思,请更新,我会尝试进行相应的编辑。

      【讨论】:

        【解决方案4】:

        根据您在 michael 帖子的 cmets 中的描述,您最好从 IPlayer 接口继承,或者如果 Part1 和 Part2 相同,则使用基类。

        public class Player
        {
            protected void Part1() { /* ... */ };
            protected void Part2() { /* ... */ };
        }
        
        public class HumanPlayer : Player
        {
            public void GetMove()
            {
                Part1();
                GetMouseClick();
                Part2();
            }
        }
        
        public class BotPlayer : Player
        {
            public void GetMove()
            {
                Part1();
                Part2();
            }
        }
        

        这样你就得到了 Player 对象,你仍然可以同样对待。

        List<Player> players = new List<Player>()
            {
                new BotPlayer(), 
                new HumanPlayer()
            };
        
        // ...
        
        foreach (Player p in this.players)
            p.GetMove();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-09
          • 2012-11-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多