我正在尝试从TableLayoutPanel
中删除所有空行。到目前为止,我已经能够这样做了
private void RemoveEmptyRows()
{
for (int row = 0; row < tablePanel.RowCount - 1; 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);
}
}
有更好的方法吗?我的做法似乎太不堪重负了。
答案 0 :(得分:5)
我不会说有更好的方法,只是你的代码有一些缺陷。你可以依靠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--;
}
}
}
您应该从上到下进行迭代,因为RowCount
在您的外部foreach循环中对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--;
});