使用特别命名的项目设计 for 循环

Designing a for loop with specifically named items

我在为 GUI 编写代码时经常 运行 遇到这种情况,我想知道这是解决此问题的最佳实践方法。情况是这样的:

我的 GUI 上有许多相同的项目,它们具有不同的变量名称,即我有 10 个 'identical' 个按钮,它们分别命名为 Button1、Button2、Button3 等...

按钮的显示文本在代码中更新,我想检查它们是否满足特定条件何时更新,然后根据该条件更改文本颜色。所以对于 button1 我会写:

if (Button1.text == "true"){
    Button1.textcolor = blue}
else if (Button1.text == "false"){
    Button1.textcolor = red}

现在看来,必须为 10 个按钮中的每一个都重新编写这段代码似乎是多余的,将 Button1 的变量名替换为 Button2 的变量名,依此类推,直到 Button10。有没有办法在循环中更改代码的 "Button1" 部分并保持其他所有内容相同?所以我正在寻找的伪代码示例是:

for (all buttons in (button1-button10)){
    if (thisbutton.text == "true"){
        thisbutton.textcolor = blue}
    else if (thisbutton.text == "false"){
        thisbutton.textcolor = red}}

我不知道如何最好地处理这种情况,希望得到有关这方面的意见和指导。

谢谢

当你有一组相似的对象时,不要为这些对象的每个实例创建一个变量,而是将它们放入一个集合中。然后你可以很容易地循环这个列表并操作其中的对象:

var buttons = new List<Button>();

// put the buttons into the list using buttons.Add

for (var b in buttons)
{
    if (b.text == "true")
    {
        b.textcolor = blue
    }
    else 
    {
        b.textcolor = red
    }
}

您还可以使用 GridView 将所有这些按钮放入不规则网格中。

创建您自己的按钮。

using System.Windows.Forms;
using System.Drawing;

namespace TestApp
{
    public class TheButton : Button
    {
        public void ChangeColor()
        {
            ForeColor = (Text == "true")  ? Color.Blue : Color.Red ;

        }
    }
}

重建您的解决方案,您应该会在工具箱中看到 TheButton,在您的表单中,添加一个容器 class,就像一个面板,然后添加您的 TheButton 实例 class。

然后您可以编写一个方法,例如:

    private void ChangeAllButtons()
    {
        foreach (var control in panel1.Controls.Cast<object>().Where(control => (control as TheButton) != null))
        {
            (control as TheButton).ChangeColor();
        }
    }

您必须决定调用 ChangeAllButtons() 的最佳位置。

有很多方法可以解决这个问题。

由于设计者将按钮创建为 window/panel 的字段,要列出它们,您必须分析 WPF 树(或在主视图上使用反射window 不是很优雅的面板。

要获得所有 Button children 你可以使用这个方法:

public static IEnumerable<T> EnumVisualOfType<T>(Visual visual) where T : Visual
{
    for (var i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
    {
        var visualChild = (Visual)VisualTreeHelper.GetChild(visual, i);

        foreach (var child in EnumVisualOfType<T>(visualChild))
            yield return child;

        var childVisual = visualChild as T;

        if (childVisual != null)
            yield return childVisual;
    }
}

然后调用它:

var allButtons = EnumVisualOfType<Button>(window).ToList();

并且您拥有所有按钮的列表(当然,您可以根据需要过滤特定的 属性)并且您可以编写一次代码并在 foreach 循环中使用它。

您还可以在创建面板时明确地将所有按钮添加到列表中,但是您必须记住每次创建新面板时都手动添加它们。