简体   繁体   English

使用专门命名的项目设计一个for循环

[英]Designing a for loop with specifically named items

I often run into this situation when writing code for a GUI and would like to know would be a best-practice way of solving this. 在为GUI编写代码时,我经常遇到这种情况,并且想知道这是解决此问题的最佳实践方法。 The situation is this: 情况是这样的:

I have a number of identical items on my GUI which have different variable names, ie I have 10 'identical' buttons which are named Button1, Button2, Button3, etc... 我的GUI上有许多相同的项目,它们具有不同的变量名,即我有10个“相同”按钮,分别名为Button1,Button2,Button3等。

The buttons' displayed text is updated in the code and I want to check when they are updated if they meet a certain condition and then change the text color based on that condition. 按钮的显示文本已在代码中更新,我想检查它们是否满足特定条件,何时更新,然后根据该条件更改文本颜色。 So for button1 I would write: 所以对于button1,我会写:

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

Now it seems redundant to have to write this code again for each of the 10 buttons, replacing Button1's variable name with Button2's and so on up until Button10. 现在似乎不得不为10个按钮中的每个按钮再次编写此代码,用Button2替换Button1的变量名,依此类推,直到Button10。 Is there a way to change the "Button1" part of the code in a loop and keep everything else the same? 有没有办法在循环中更改代码的“ Button1”部分并使其他所有内容保持不变? So a pseudo-code example of what I'm looking for would be: 因此,我正在寻找的伪代码示例将是:

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

I don't know how to best approach this scenario and would appreciate input and guidance on this. 我不知道如何最好地解决这种情况,并希望对此提供意见和指导。

Thanks 谢谢

Whenever you have a set of similar objects don´t create a variable for every instance of those objects, instead put them into one single collection. 只要有一组相似的对象,就不要为这些对象的每个实例创建一个变量,而是将它们放入一个单独的集合中。 Then you can easily loop this list and manipulate the objects within it: 然后,您可以轻松地循环此列表并操作其中的对象:

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
    }
}

You can also use a GridView to put all those buttons into a ragular grid. 您还可以使用GridView将所有这些按钮放入一个网格中。

Create your own button. 创建自己的按钮。

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

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

        }
    }
}

Rebuild your solution, and you should see TheButton in the toolbox, in your form, Add a container class, like a panel, and add your instances of TheButton class. 重建您的解决方案,您应该在工具箱中的窗体中看到TheButton,添加一个容器类(如面板),并添加TheButton类的实例。

You could then write a method, like: 然后,您可以编写一个方法,例如:

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

You will have to decide the best place to call ChangeAllButtons(). 您将必须确定调用ChangeAllButtons()的最佳位置。

There are many ways to approach this. 有很多方法可以解决此问题。

As the buttons are created by the designer as fields of the window/panel, to list them you have to analyse the WPF tree (or use reflection on the main window panel which it's not really elegant). 由于按钮是由设计人员创建为窗口/面板的字段,要列出这些按钮,您必须分析WPF树(或在主窗口面板上使用反射,但反射效果并不佳)。

To get all the Button children you can use this method: 要获取所有Button子级,可以使用以下方法:

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;
    }
}

And then invoke it: 然后调用它:

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

And you have the list of all the buttons (which you can, of course, filter on a specific property if you like) and you can write your code once and use it in a foreach loop. 并且您拥有所有按钮的列表(当然,您可以根据需要过滤特定的属性),并且可以编写一次代码并将其在foreach循环中使用。

You can also explicitly add all your buttons to a list when the panel is created, but then you will have to remember to add them manually every time you create a new one. 创建面板时,您也可以将所有按钮显式添加到列表中,但是每次创建一个新按钮时,都必须记住手动将它们添加。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM