あなたのコードにいくつかの欠陥があることを除いて、より良い方法があるとは言いません。Linq
もう少し簡潔にすることを信頼できますが、この種のことを行うためにLinqを多用するべきではないため、エレガントでなく、読みにくく、デバッグできない可能性があります(個人的には好きです!) 。既存のコードに対して行うべきことは次のとおりです。
private void RemoveEmptyRows()
{
for (int row = tablePanel.RowCount -1; row >= 0; row--)
{
bool hasControl = false;
for (int col = 0; col < tablePanel.ColumnCount; col++)
{
if (tablePanel.GetControlFromPosition(col, row) != null)
{
hasControl = true;
break;
}
}
if (!hasControl)
{
tablePanel.RowStyles.RemoveAt(row);
tablePanel.RowCount--;
}
}
}
外側のforeachループでRowCount
評価するときに変更される可能性があるため、上から下に繰り返す必要があります。row
RowStyle
また、単にを実行して削除した後、行を削除する必要がありますRowCount--
。
Linq
バージョンは次のとおりです。
Enumerable.Range(0, tablePanel.RowCount)
.Except(tablePanel.Controls.OfType<Control>()
.Select(c => tablePanel.GetRow(c)))
.Reverse()
.ToList()
.ForEach(rowIndex =>
{
tablePanel.RowStyles.RemoveAt(rowIndex);
tablePanel.RowCount--;
});
これを何をするかについて分解するには(Linqにあまり精通していない場合):
var listOfAllRowIndices = Enumerable.Range(0, tablePanel.RowCount);
var listOfControlsInTableLayoutPanel = tablePanel.Controls.OfType<Control>();
var listOfRowIndicesWithControl = listOfControlsInTableLayoutPanel.Select(c => tablePanel.GetRow(c));
var listOfRowIndicesWithoutControl = listOfAllRowIndices.Except(listOfRowIndicesWithControl);
var listOfRowIndicesWithoutControlSortedInDescendingOrder = listOfRowIndicesWithoutControl.Reverse(); //or .OrderByDescending(i => i);
その後:
listOfRowIndicesWithoutControlSortedInDescendingOrder.ToList().ForEach(rowIndex =>
{
tablePanel.RowStyles.RemoveAt(rowIndex);
tablePanel.RowCount--;
});
読みやすくなる可能性がありますが、効率が低い別のLinqバージョン:
Enumerable.Range(0, tableLayoutPanel1.RowCount)
.Where(rowIndex => !tableLayoutPanel1.Controls.OfType<Control>()
.Select(c => tableLayoutPanel1.GetRow(c))
.Contains(rowIndex))
.Reverse()
.ToList()
.ForEach(rowIndex =>
{
tablePanel.RowStyles.RemoveAt(rowIndex);
tablePanel.RowCount--;
});