4

からすべての空の行を削除しようとしてい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);
    }
}

これのより良い方法はありますか?私のアプローチはあまりにも圧倒されているようです。

4

1 に答える 1

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--;
        }
    }
}
  1. 外側のforeachループでRowCount評価するときに変更される可能性があるため、上から下に繰り返す必要があります。row

  2. 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--;
    });
于 2012-11-03T07:44:45.927 に答える