Scrolling issues with .net scrolling

aewarnick

Senior Contributor
Joined
Jan 29, 2003
Messages
1,031
Does anyone know how to disable the feature of AutoScroll that causes a control to be automatically scrolled into veiw when it is focused?

I declared this in my class, overriding the base class method but the control still scrolls down when the focused control is out of view.

void ScrollControlIntoView(Control c)
{
//did nothing here hoping to fix the problem.
}

That is my FIRST question.
The second is this:

I have a feeling, disabling that feature is impossible. So I have created my own scolling panel derived from Panel.

Everything works greate except when I resize a control within the panel with the mouse movement. I really get issues then even if I only move the mouse one pixel down, making the control one pixel bigger. But when I resize the control any other way everything works great! What is going on!?
Here is the Panel class:
C#:
public class aPanel : Panel
	{
		bool causedByScroll=false;
		ArrayList controlList=new ArrayList(2);
		ArrayList pointsList=new ArrayList(2);
		Rectangle controlsRect= Rectangle.Empty;
		VScrollBar vScrollBar=new VScrollBar();
		HScrollBar hScrollBar=new HScrollBar();
		bool autoScroll=true;
		public bool AutoScroll
		{
			get{return this.autoScroll;}
			set{this.autoScroll=value; this.SetBars();}
		}
//-----------------
		public aPanel()
		{
			this.Controls.Add(this.vScrollBar);
			this.Controls.Add(this.hScrollBar);
			this.vScrollBar.Scroll += new ScrollEventHandler(this.vScrollBar_Scroll);
			this.hScrollBar.Scroll += new ScrollEventHandler(this.hScrollBar_Scroll);
			this.MouseUp += new MouseEventHandler(this.mouseUp);
		}
//-----------------
		void SetBars()
		{
			if(causedByScroll)
				return;
			if(this.controlsRect.Height > this.Height)
			{
				this.vScrollBar.SetBounds(this.Width-this.vScrollBar.Width, 0, this.vScrollBar.Width, this.Height);
				//this.vScrollBar.Minimum= this.hScrollBar.Height*2-this.ClientRectangle.Height;
				//this.vScrollBar.Maximum= this.controlsRect.Height;
				this.vScrollBar.Maximum= this.controlsRect.Height+this.hScrollBar.Height*2-this.ClientRectangle.Height;
				this.vScrollBar.Visible=true;
			}
			else
			{
				this.vScrollBar.Value=0;
				this.vScroll(0);
				this.vScrollBar.Visible=false;
			}
			if(this.controlsRect.Width > this.Width)
			{
				this.hScrollBar.SetBounds(0, this.Height-this.hScrollBar.Height, this.Width-this.vScrollBar.Width, this.hScrollBar.Height);
				this.hScrollBar.Visible=true;
			}
			else
			{
				this.hScrollBar.Value=0;
				this.hScroll(0);
				this.hScrollBar.Visible=false;
			}
		}
//-----------------
		void vScrollBar_Scroll(object s, ScrollEventArgs e)
		{
			this.vScroll(e.NewValue);
		}
//-----------------
		void hScrollBar_Scroll(object s, ScrollEventArgs e)
		{
			
		}
//-----------------
		void vScroll(int v)
		{
			this.causedByScroll=true;
			for(int i=0; i<this.controlList.Count; i++)
			{
				((Control)this.controlList[i]).Location=new Point(((Control)this.controlList[i]).Location.X, ((Point)this.pointsList[i]).Y-v);
			}
			this.causedByScroll=false;
		}
//-----------------
		void hScroll(int v)
		{
		}
//-----------------
		protected override void OnMouseWheel(MouseEventArgs e)
		{
			if(!this.vScrollBar.Visible)
				return;
			base.OnMouseWheel(e);
			int v= this.vScrollBar.Value+-e.Delta;
			if(v > this.vScrollBar.Maximum)
				v= this.vScrollBar.Maximum;
			else if(v < this.vScrollBar.Minimum)
				v= this.vScrollBar.Minimum;
			this.vScrollBar.Value= v;
			this.vScroll(this.vScrollBar.Value);
		}
//-----------------
		protected override void OnLayout(LayoutEventArgs e)
		{
			base.OnLayout(e);
			if(e.AffectedControl==null || this.causedByScroll || e.AffectedControl is ScrollBar || e.AffectedControl==this || e.AffectedProperty != "Bounds")
				return;
			if(!this.AutoScroll)
			{
				this.vScrollBar.Visible=false;
				this.hScrollBar.Visible=false;
				return;
			}
			int index= this.controlList.IndexOf(e.AffectedControl);
			if(index > -1) //location may have changed
			{
				//this.vScrollBar.Value=0;
				//this.vScroll(0);
				if(((Point)this.pointsList[index]).Y != e.AffectedControl.Location.Y+this.vScrollBar.Value)
				{
	//a.MB.Show(e.AffectedControl.Location.Y+" val="+this.vScrollBar.Value+"  max="+this.vScrollBar.Maximum+" pt="+((Point)this.pointsList[index]).Y);
					this.pointsList[index]=new Point(e.AffectedControl.Location.X, e.AffectedControl.Location.Y);
				}
			}
			else
			{
				this.controlList.Add(e.AffectedControl);
				this.pointsList.Add(new Point(e.AffectedControl.Location.X, e.AffectedControl.Location.Y));
			}

			this.controlsRect= Rectangle.Empty;
			for(int i=0; i<this.controlList.Count; i++)
			{
				Control c= (Control)this.controlList[i];
				Point p= (Point)this.pointsList[i];
			
				if(p.Y < this.controlsRect.Y)
					this.controlsRect.Y= p.Y;
				if(p.X < this.controlsRect.X)
					this.controlsRect.X= p.X;
				if(p.Y+c.Height+this.AutoScrollMargin.Height > this.controlsRect.Bottom)
					this.controlsRect.Height= p.Y+c.Height+this.AutoScrollMargin.Height;
				if(p.X+c.Width+this.AutoScrollMargin.Width > this.controlsRect.Right)
					this.controlsRect.Width= p.X+c.Width+this.AutoScrollMargin.Width;
			}

			this.SetBars();
		}
//-----------------
		void mouseUp(object s, MouseEventArgs e)
		{
			if(this.vScrollBar.Visible)
				this.vScrollBar.Focus();
		}
	}
I think Microsoft came accross the same problem because when I use AutoScroll and resize a control with the mouse, the Value of the ScrollBar is set to 0 thus eliminating the problem. I would think that ms would have come up with better scrolling features than that.

Does anyone know how to fix this problem or know of any better scrolling controls or how to make the mouse wait?
 
Last edited:
Searched all over for the solution to this, and found nothing. But some experimentation shows there is an easy answer!

Place the following override on the control with AutoScroll set true (the parent control):
Code:
protected override Point ScrollToControl(Control activeControl)
{
	return this.AutoScrollPosition;
}

This works because ScrollToScroll returns the new scroll position for the parent that is required to move the required location on the child control (as determined by activeControll.AutoScrollOffset) into view.

If you simply return the current AutoScrollPosition in response to all requests to scroll a control into view, then the parent control does not scroll at all from its current position.

Somewhat late reply, but hopefully this helps others searching for a solution. :cool:
 
Back
Top