// set forcereposition if the vscroll pos does not change but something like a control resize may have messed about with the positioning private void ScrollTo(int newscrollpos, bool forcereposition) { //System.Diagnostics.Debug.WriteLine("ScrollTo " + newscrollpos ); //System.Diagnostics.Debug.WriteLine("From " + Environment.StackTrace.StackTrace("ScrollTo",5)); int maxy = 0; List <Point> cposnorm = new List <Point>(); Point flowpos = new Point(0, 0); // for flow int dwidth = DisplayRectangle.Width; int rowymax = 0; foreach (Control c in Controls) { if (!(c is ExtScrollBar) && c.Visible) // if in a tab, when tab is turned on, we get a call but will all things invisible (it comes thru resize) { // therefore setting scroll pos to zero. This stage double checks we do not have controls if (-c.Top > scrollpos) // below zero meaning we have lost scroll pos. If so, set it back { //System.Diagnostics.Debug.WriteLine(" Before Control " + c.Text + " " + c.Size + " " + c.Location + " " + c.Visible + " before " + scrollpos + " set to " + -c.Top); scrollpos = -c.Top; newscrollpos = scrollpos; } } } foreach (Control c in Controls) { if (!(c is ExtScrollBar) && c.Visible) { if (FlowControlsLeftToRight) { if (flowpos.X + c.Width + c.Margin.Horizontal >= dwidth && flowpos.X > 0) { flowpos = new Point(0, flowpos.Y + rowymax); rowymax = 0; } cposnorm.Add(new Point(flowpos.X + c.Margin.Left, flowpos.Y + c.Margin.Top)); flowpos.X += c.Width + c.Margin.Horizontal; rowymax = Math.Max(rowymax, c.Height + c.Margin.Vertical); maxy = flowpos.Y + c.Height - 1 + c.Margin.Vertical; } else { cposnorm.Add(new Point(c.Left, c.Top + scrollpos)); maxy = Math.Max(maxy, c.Top + scrollpos + c.Height - 1); // -1 because top+height = 1 pixel beyond last displayed } } //System.Diagnostics.Debug.WriteLine(" Control " + c.Name + " " + c.Size + " " + c.Location + " " + c.Visible + " maxy " + maxy); } int maxscr = maxy - ClientRectangle.Height + (ScrollBar?.LargeChange ?? 0); // large change is needed due to the way the scroll bar works (which matches the windows scroll bar) if (maxy <= ClientRectangle.Height) // limit.. { //System.Diagnostics.Debug.WriteLine(" Maxy <= Client Height, set to zero"); newscrollpos = 0; } else if (newscrollpos > maxscr) { newscrollpos = maxscr; } //System.Diagnostics.Debug.WriteLine(" Maxy " + maxy + " CH "+ ClientRectangle.Height + " maxscr " + maxscr + " new scr " + newscrollpos + " old scroll " + scrollpos); if (newscrollpos != scrollpos || (FlowControlsLeftToRight && forcereposition)) // only need forcereposition on flowing { SuspendLayout(); ignorelocationchange++; int posi = 0; foreach (Control c in Controls) { if (!(c is ExtScrollBar) && c.Visible) // new! take into account visibility { c.Location = new Point(cposnorm[posi].X, cposnorm[posi].Y - newscrollpos); posi++; //System.Diagnostics.Debug.WriteLine(" flow and set " + c.Name + " to " + c.Location + " Using sp " + newscrollpos); } } ignorelocationchange--; ResumeLayout(); Update(); // force redisplay } if (ScrollBar != null) { ScrollBar.SetValueMaximumMinimum(newscrollpos, maxscr, 0); //System.Diagnostics.Debug.WriteLine(" set bar from {0} to {1} maxscr {2} maxy {3} ClientH {4}", scrollpos, newscrollpos, maxscr , maxy , ClientRectangle.Height); } scrollpos = newscrollpos; //System.Diagnostics.Debug.WriteLine("Set scroll pos to " + scrollpos); }
// set forcereposition if the vscroll pos does not change but something like a control resize may have messed about with the positioning private int ScrollTo(int newscrollpos, bool forcereposition) { //System.Diagnostics.Debug.WriteLine("Scroll panel is " + ClientRectangle + " curscrollpos " + scrollpos); //System.Diagnostics.Debug.WriteLine("From " + Environment.StackTrace.StackTrace("ScrollTo",5)); int maxy = 0; List <Point> cposnorm = new List <Point>(); Point flowpos = new Point(0, 0); int dwidth = DisplayRectangle.Width; int rowymax = 0; foreach (Control c in Controls) { if (!(c is ExtScrollBar)) { if (FlowControlsLeftToRight) { if (flowpos.X + c.Width + c.Margin.Horizontal >= dwidth && flowpos.X > 0) { flowpos = new Point(0, flowpos.Y + rowymax); rowymax = 0; } cposnorm.Add(new Point(flowpos.X + c.Margin.Left, flowpos.Y + c.Margin.Top)); flowpos.X += c.Width + c.Margin.Horizontal; rowymax = Math.Max(rowymax, c.Height + c.Margin.Vertical); maxy = flowpos.Y + c.Height + c.Margin.Vertical; } else { cposnorm.Add(new Point(c.Left, c.Top + scrollpos)); maxy = Math.Max(maxy, c.Top + scrollpos + c.Height); } // System.Diagnostics.Debug.WriteLine("Control " + c.Text + " " + c.Size + " " + c.Location + " maxy " + maxy); } } int maxscr = maxy - ClientRectangle.Height + (ScrollBar?.LargeChange ?? 0); // large change is needed due to the way the scroll bar works (which matches the windows scroll bar) if (maxy <= ClientRectangle.Height) // limit.. { newscrollpos = 0; } else if (newscrollpos > maxscr) { newscrollpos = maxscr; } // System.Diagnostics.Debug.WriteLine("Maxy " + maxy + " maxscr " + maxscr + " new scr " + newscrollpos + " old scroll " + scrollpos); if (newscrollpos != scrollpos || (FlowControlsLeftToRight && forcereposition)) // only need forcereposition on flowing { SuspendLayout(); ignorelocationchange = true; int posi = 0; foreach (Control c in Controls) { if (!(c is ExtScrollBar)) { c.Location = new Point(cposnorm[posi].X, cposnorm[posi].Y - newscrollpos); posi++; } } ignorelocationchange = false; ResumeLayout(); Update(); // force redisplay } if (ScrollBar != null) { ScrollBar.SetValueMaximumMinimum(newscrollpos, maxscr, 0); // System.Diagnostics.Debug.WriteLine("Scroll {0} to {1} maxscr {2} maxy {3} ClientH {4}", scrollpos, newscrollpos, maxscr , maxy , ClientRectangle.Height); } scrollpos = newscrollpos; return(maxy); }