Разработка цикла 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.
Вы также можете явно добавить все свои кнопки в список при создании панели, но тогда вам придется не забывать добавлять их вручную каждый раз, когда вы создаете новую.