使用特别命名的项目设计 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 循环中使用它。
您还可以在创建面板时明确地将所有按钮添加到列表中,但是您必须记住每次创建新面板时都手动添加它们。
我在为 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 循环中使用它。
您还可以在创建面板时明确地将所有按钮添加到列表中,但是您必须记住每次创建新面板时都手动添加它们。