Разработка цикла for со специально названными элементами

Я часто сталкиваюсь с такой ситуацией, когда пишу код для графического интерфейса, и хотел бы знать, что это лучший способ решения этой проблемы. Ситуация такая:

У меня есть несколько идентичных элементов в моем графическом интерфейсе, которые имеют разные имена переменных, то есть у меня есть 10 "идентичных" кнопок, которые называются 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}}

Я не знаю, как лучше подходить к этому сценарию, и был бы признателен за информацию и рекомендации по этому вопросу

Спасибо

3 ответа

Решение

Когда у вас есть набор похожих объектов, не создавайте переменную для каждого экземпляра этих объектов, вместо этого поместите их в одну коллекцию. Затем вы можете легко зациклить этот список и манипулировать объектами в нем:

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 на панели инструментов, в вашей форме, добавить класс контейнера, такой как панель, и добавить свои экземпляры класса TheButton.

Затем вы можете написать метод, например:

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

Вам нужно будет выбрать лучшее место для вызова ChangeAllButtons().

Есть много способов приблизиться к этому.

Так как кнопки создаются дизайнером в виде полей окна / панели, для их перечисления необходимо проанализировать дерево WPF (или использовать отражение на панели главного окна, что не очень элегантно).

Чтобы получить все 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;
    }
}

И затем вызвать его:

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

И у вас есть список всех кнопок (которые вы можете, конечно, фильтровать по определенному свойству, если хотите), и вы можете написать свой код один раз и использовать его в цикле foreach.

Вы также можете явно добавить все свои кнопки в список при создании панели, но тогда вам придется не забывать добавлять их вручную каждый раз, когда вы создаете новую.

Другие вопросы по тегам