使用 foreach 重置每个按钮的文本和启用值

本文关键字:文本 启用 按钮 foreach 使用 | 更新日期: 2023-09-27 18:34:55

我用C#(Visual Studio Winform(做了一个简单的井字游戏。我添加了一个菜单条,其中包含一个文件菜单,其中包含"新游戏"选项。我正在尝试做的是重置所有按钮的文本,并且我已经禁用了它们,因此我想再次启用它们。当我在窗体上只有一个菜单条和按钮时,我使用了以下代码,并且它起作用了。但是现在我在表单中添加了一个标签,并且此代码不起作用。我知道我可以简单地为每个按钮一一重置值,但我想知道添加标签时出了什么问题。提前谢谢。:)

try
     {
        foreach (Control c in Controls)
        {
           Button b = (Button)c;
           b.Text = "";
           b.Enabled = true;
        }
     }
     catch { }

使用 foreach 重置每个按钮的文本和启用值

您的代码不再工作,因为控件集合现在还包含 Label,因此当您的循环到达 Label 控件时,它会在此行引发异常

 Button b = (Button)c;

您不能将标签转换为按钮,但此异常会被空的 try catch 吞噬,并且您的循环会在没有任何警告的情况下终止。 空的尝试/捕获被认为是一种不好的做法,最好删除它们并让异常显示。

使用 OfType 枚举扩展来仅获取 Button 类型的控件可以避免您的问题。其余代码现在不需要任何其他更改。

foreach (Button b in Controls.OfType<Button>())
{
   b.Text = "";
   b.Enabled = true;
}

但请记住,此循环适用于表单控件容器。如果添加某种其他类型的容器(如 GroupBox 或 Panel(并在该控件内移动按钮,则需要循环访问该容器 Controls 属性。

编辑
要从循环中排除特定按钮,您可以向 OfType 返回的序列添加对 IEnumerable<T>.Where 的调用。例如

foreach (Button b in Controls.OfType<Button>().Where(x => x.Name != "button10")
.....
 this.Controls.OfType<Button>().ToList().ForEach(b => { b.Text = ""; b.Enabled = true; });