首页 > 解决方案 > C#使用循环检查Windows窗体中的按钮点击

问题描述

我正在为一个类项目用 C# 创建游戏 Qwixx 的一个版本。我目前有从 P1R2 到 P1R12 的按钮,从左到右连续排列。单击 End Turn 按钮时,它会禁用任何带有 X 或 - 而不是数字的按钮。

        private void P1R2_Click(object sender, EventArgs e)
    {
        if (P1R2Clicked == false)
        {
            P1R2.Text = "X";
            P1R2Clicked = true;
        }
        else
        {
            P1R2.Text = "2";
            P1R2Clicked = false;
        }
    }

    private void P1R3_Click(object sender, EventArgs e)
    {
        if (P1R3Clicked == false)
        {
            P1R3.Text = "X";
            if (P1R2.Text == "2")
            {
                P1R2.Text = "-";
            }
            P1R3Clicked = true;
        }
        else
        {
            P1R3.Text = "3";
            if (P1R2.Text == "-")
            {
                P1R2.Text = "2";
            }
            P1R3Clicked = false;
        }
    }

    private void P1R4_Click(object sender, EventArgs e)
    {
        if (P1R4Clicked == false)
        {
            P1R4.Text = "X";
            if (P1R3.Text == "3")
            {
                P1R3.Text = "-";
            }
            if (P1R2.Text == "2")
            {
                P1R2.Text = "-";
            }
            P1R4Clicked = true;
        }
        else
        {
            P1R4.Text = "4";
            if (P1R3.Text == "-")
            {
                P1R3.Text = "3";
            }
            if (P1R2.Text == "-")
            {
                P1R2.Text = "2";
            }
            P1R4Clicked = false;
        }
    }

使用上面的代码,我确保用户可以多次单击按钮并在显示数字时将按钮上的文本更改为左侧。我试图找到一种方法来通过另一个类中的方法运行这些检查,我可以在其中迭代循环。问题是我找不到检查变量 P1R#Clicked 以推动循环的方法。或者如何运行 P1R#.Text。想法?

编辑: 红排

        private void P1Red_Click(object sender, EventArgs e)
    {
        var index = Array.IndexOf(P1RedButtons, sender);
        if (index == 10)
        {
            foreach (Button s in P1RRow.Controls.OfType<Button>())
            {
                if (s.Text == "X")
                {
                    P1NoRed++;
                }
            }
            P1RedButtons[index].Text = P1NoRed < 5 ? (index + 2).ToString() : "X";
            P1RedClicked[index] = P1NoRed < 5 ? !P1RedClicked[index] : P1RedClicked[index];
            P1RedX[index] = P1NoRed < 5 ? !P1RedX[index] : P1RedX[index];
            P1NoRed = 0;
        }
        else
        {
            P1RedButtons[index].Text = P1RedClicked[index] ? (index + 2).ToString() : "X";
        }
            if (index != 0)
            {
                if (P1RedClicked[index - 1] == false)
                {
                    int red1found = Array.LastIndexOf(P1RedX, true, index - 1);

                    for (int j = index - 1; j > red1found; j--)
                    {
                        P1RedButtons[j].Text = P1RedClicked[index] ? (j + 2).ToString() : "-";
                    }
                }
            }
        P1RedClicked[index] = !P1RedClicked[index];
        P1RedX[index] = !P1RedX[index];
    }

在这段代码中,P1NoRed 是一个计数器,用于检查是否至少有 5 个按钮被点击并在它们上面有一个“X”。在该行中有 5 个其他“X”之前,它不允许单击数字 12。此时一切正常,包括将“-”放在单击的数字的左侧,如果再次单击则将其撤消。End Turn 按钮锁定这些按钮并禁用任何带有“X”或“-”的按钮。我目前正在寻找一种方法来跟踪在按下 End Turn 按钮之前在一个回合中单击的按钮数量。根据游戏规则,轮到你可以点击 2 个按钮,如果不是轮到你,可以点击 1 个按钮。我知道在事件的某个地方我需要一个计数器,可能会扫描 P1RedClicked 数组以获取真实值。我的想法是,当单击第二个 x 以禁用从最右边的“X”到左端的行中的任何按钮时。我愿意接受建议,因为我正在努力。非常感谢@Enigmativity 迄今为止提供的所有帮助。

标签: c#

解决方案


我建议您创建按钮数组并检查变量,然后使用这些数组,而不是使用不同的变量。

从这个开始:

private Button[] P1Buttons;
private bool[] P1ButtonsClicked;

现在,Form_Load有这个代码:

P1Buttons = new []
{
    P1R2, P1R3, P1R4, P1R5, P1R6, P1R7,
    P1R8, P1R9, P1R10, P1R11, P1R12, 
};

P1ButtonsClicked = P1Buttons.Select(b => false).ToArray();

Array.ForEach(P1Buttons, b => b.Click += P1Button_Click);

您将所有Click事件附加到此方法:

private void P1Button_Click(object sender, EventArgs e)
{
    var index = Array.IndexOf(P1Buttons, sender);
    if (P1ButtonsClicked[index] == false)
    {
        P1Buttons[index].Text = "X";
        P1ButtonsClicked[index] = true;
    }
    else
    {
        P1Buttons[index].Text = "2";
        P1ButtonsClicked[index] = false;
    }
}

您现在只需要重写该代码来处理从index == 0(button P1R2) 到index == 10(button P1R12) 的所有情况。

我建议你也改变一下你对如何编写事件处理程序的想法。尝试这个:

private void P1Button_Click(object sender, EventArgs e)
{
    var index = Array.IndexOf(P1Buttons, sender);
    P1Buttons[index].Text = P1ButtonsClicked[index] ? "2" : "X";
    P1ButtonsClicked[index] = !P1ButtonsClicked[index];
}

消除if语句通常是减少重复和错误的好方法。


推荐阅读