2012-11-03 108 views
4

我試圖從TableLayoutPanel刪除所有空行。到目前爲止,我已能夠這樣做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); 
    } 
} 

有沒有更好的方法呢?我的方法似乎太不知所措了。

回答

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循環對row評估時,因爲RowCount下可以改變。

  2. 您還應該在刪除RowStyle後簡單地通過執行​​3210刪除該行。

這裏是一個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--; 
    }); 
+0

+1迭代底部到頂部....和個人而言,我恨LINQ,不爲別的原因,語法是如此密集,我覺得它堅不可摧,因此我的LINQ解決方案往往需要更長的時間才能開發併成爲越野車引導!通常情況下,我發現非linq版本的編寫速度更快,而且維護起來也更容易......但是也許我只是需要更多的LINQ,我不願意使用它。嘆。 – corlettk

+2

@corlettk Linq很酷,我喜歡它。對我來說真正的好處是,它使我免於爲簡單任務編寫重複性明顯的代碼。但是,我不喜歡Linq複雜的任務。多個linq語句使得很難理解。例如,我喜歡'myList.Where(this and that).Select(so and so).OrderBy(condition)'這樣的代碼,它非常簡單易讀,其中我討厭'myList.GroupBy(condition).ToDictionary (選擇器,選擇器,地獄很多其他選擇器).Distinct()。Zip(另一個複雜的字典)' – nawfal

+0

感謝您的自下而上的方法。我也遇到了一些奇怪的行爲。我會試試這個。 – nilobarp