Похоже, у вас есть вложенный дизайн. В каждой строке по 5 меток размещаются разные TableLayoutPanels, а TLP_IO_Info
, который является TableLayoutPanel, размещает другие TableLayoutPanels. В событии DoWork
BackgroundWorker у вас есть for..loop
для изменения Backcolor
внутренних элементов управления в соответствии с текущим состоянием устройств, которые вы читаете из массива INPUT
int , Пожалуйста, исправьте меня.
Я хотел бы предложить это:
foreach (var tlp in TLP_IO_Info.Controls.OfType<TableLayoutPanel>()
.Where(x => x.Name.StartsWith("ED527_")))
{
if (tlp.GetControlFromPosition(4, 0) is Label lbl)
{
var state = // get the state of the current device from INPUT array
var stateColor = state == 1 ? Color.Green : Color.White;
var stateText = state == 1 ? "ON" : "OFF";
this.Invoke(new Action(() =>
{
tlp.BackColor = stateColor;
tlp.Controls.OfType<Label>().ToList().ForEach(l => l.BackColor = stateColor);
lbl.Text = stateText;
}));
}
}
Или это, чтобы исключить избыточный код:
var stateColors = new[] { Color.White, Color.Green };
var stateTexts = new[] { "OFF", "ON" };
foreach (var tlp in TLP_IO_Info.Controls.OfType<TableLayoutPanel>()
.Where(x => x.Name.StartsWith("ED527_")))
{
if (tlp.GetControlFromPosition(4, 0) is Label lbl)
{
var state = // get the state of the current device from INPUT array
this.Invoke(new Action(() =>
{
tlp.BackColor = stateColors[state];
tlp.Controls.OfType<Label>().ToList()
.ForEach(l => l.BackColor = stateColors[state]);
lbl.Text = stateTexts[state];
}));
}
}
Обратите внимание, что я имею удалены дорогие блоки try..catch
, поскольку этот код не будет генерировать никаких исключений.
Что касается массива INPUT
, я предлагаю заменить его на Dictionary<string, int>
для хранения текущего состояния каждого устройства. поскольку (согласно предоставленной вами ссылке) каждое устройство имеет уникальный IOLineNumber
, поэтому вы можете легко установить / получить текущее состояние каждого из них.
⍰ Возможно, что-то подобное уже есть в библиотеке?