1
votes

Got a TableLayoutPanel in my winform, to increase loading speed. I tried suspending it's layout, adding the rows and resume Layout. Sadly if I suspend until all rows are added, I get a horizontal scroll bar that does not appear if I resume Layout inbefore adding or suspend after adding each row again. scrollbar

Msdn states "Add method reapplies the table layout to all the controls":

That's what I have to reproduce by my own code after all rows are added. However adding another row in the end does not produce the layout not suspending at all does.

I tried:

  • replace the first column's content with new Control() just to test if the content was too large.
  • change the contents size -> led to smaller content, more whitespace and same problem
  • change the tableLayoutPanel's size -> led to a smaller control with still the same problem
  • change the first column's size (as the later two ones have absolute values) from 100% to a lower percent value, autosize and a similar absolute value -> led to the last column begin oversized, still visible scrollbar
  • PerformLayout() after rows are added
  • Refresh() after rows are added
  • ResumeLayout(true) to force pending layout requests/changes (Should absolutely give me the layout I want and get without suspending, maybe buggy or something is overwritten?)
  • Update() after rows are added

tl;dr add rows, lag, no scrollbar vs suspend, add rows, horizontal scrollbar

why and how not to?


Found out that without all the suspending and resuming I experience the same problem if I add EXACTLY 5 rows: 4 work fine as no scrollbar is needed, 6 remove the horizontal scrollbar, 5 is buggy. So the problem goes deeper than layout suspending. There is definitely something wrong with adding a specifing amount of rows overall. -> outsourced to new question (required for this one) -> solved outsourced question,

paused until I stumble upon problems with Suspending again

1
I can think of a hacky quick fix, the problem seems to be that the vertical scrollbar isn't here when you begin adding, so the width is wrong. The fix would be to suspend after the vertical scrollbar is shown. Not pretty nor right, but should work. - satibel
@satibel Did suspend to delete the rows, then while adding if(i==6){ tableLayoutPanel1.ResumeLayout(); } if(i==7){ tableLayoutPanel1.SuspendLayout(); } and resuming after all rows have been added again. Sadly it's still the same, don't ask me why, it seems to be just a few pixel off. However if I for example change the code above to wait til i==15 before suspending again, it works. There seem to be very little changes with every row added so suspending after the sixth only fails by some pixel, the more rows are added without suspending the more pixel get removed? - user8098743
@satibel Tested some more things: It takes atleast 6 rows to be added while not suspended to remove the horizontal scrollbar. These 6, as far as I can tell, do not have to be the first six, but could also be somewhere in the middle (proof in comment above). However adding ~120 rows in total, these 6 feel like taking up half of the loading time. Resuming to add the last 6 rows will prevent an odd-feeling freeze during the add process but still make the control laggy and take a lot of time. However thank you, if it comes to no more ideas/answers, I'll make use of this. - user8098743

1 Answers

0
votes

This question is linked with a problem I outsourced and solved here, consider the code over there as the main solution, this is a small addition.

As described in the question's comments, there is a specific amount of rows I've to add without suspending (related to the height of the TableLayoutPanel), this seems to work in most cases (inp.Count is the amount of rows added):

tableLayoutPanel1.SuspendLayout();
int i;
while ((i = tableLayoutPanel1.Controls.Count) >= 2) {
    tableLayoutPanel1.Controls[--i].Dispose();
    tableLayoutPanel1.Controls[--i].Dispose();
    tableLayoutPanel1.Controls[--i].Dispose();
}
while (tableLayoutPanel1.RowStyles.Count > 0) {
        tableLayoutPanel1.RowStyles.RemoveAt(tableLayoutPanel1.RowStyles.Count - 1);
}
tableLayoutPanel1.RowCount = 0;
for(int i=0; i<inp.Count; i++){
    if (i > inp.Count - 6) {
        tableLayoutPanel1.ResumeLayout();
    }
//...
}

Check the above linked solution for that one case where inp.Count is not big enough to fix the horizontal scrollbar.


This improves the loading time massively, however there is still lag of visual elements, why I decided to add in tableLayoutPanel1.Hide(); at the beginning and tableLayoutPanel1.Show(); at the end.

Even hiding the parent control doesn't prevent the user from seeing how the rows disappear, also after revealing the control again, the table borders are shown first before the content itself is loaded. So this solution isn't perfect, but the extent it works to shall be enough here.