Introduction
Initially, I wrote a small article to describe what is necessary to add zoom functionality to a custom control (see Details below). There were many users who had problems using the described routines in their own code. That is the reason I decided to program a custom control library (UniversalControl.dll) and provide it with a demo project. I also added a vertical and horizontal scrollbar to the control, because it seemed to be an indispensable feature.
Usage (see also the demo project)
- Add the UniversalControl.dll library to your toolbox.
- Drag the
CUniversalControl
item in your application.
- Configure your
CUniversalControl
(set colors, enable/disable scrollbars, ...).
- Write your own drawing routine (
DrawContents(Graphics grc)
).
- Add it to the control drawing event.
cUniversalControl1.EDraw += new DDrawContents(DrawContents);
Details
The user selects the zoom area with his left mouse button, see the screenshots below:
The Code
Three routines to handle the mouse events are added to the control. The OnMouseDown
method is called when a mouse button is pressed. It sets the starting point for the new zoom area and resets its size to zero.
protected void OnMouseDown(object sender,
System.Windows.Forms.MouseEventArgs e)
{
m_blnZoom = false;
m_ZoomRect = new Rectangle(new Point(e.X, e.Y),
new Size(0, 0));
}
The OnMouseMove
updates the area to zoom based on the current mouse position as long as the left mouse button is pressed. It calls the Invalidate
method of the control to update the chosen zoom rectangle (black rectangle). Drawback: Invalidate
called without parameters updates the whole control, that may result in some flickering during the selection of the area to zoom (solution: invalidate only the necessary region).
protected void OnMouseMove(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
if (m_ZoomRect.X >= e.X)
m_ZoomRect.Width += Math.Abs(e.X - m_ZoomRect.X);
else m_ZoomRect.Width = Math.Abs(e.X - m_ZoomRect.X);
if (m_ZoomRect.Y >= e.Y)
m_ZoomRect.Height += Math.Abs(e.Y - m_ZoomRect.Y);
else m_ZoomRect.Height = Math.Abs(e.Y - m_ZoomRect.Y);
if (m_ZoomRect.X > e.X) m_ZoomRect.X = e.X;
if (m_ZoomRect.Y > e.Y) m_ZoomRect.Y = e.Y;
this.Invalidate();
}
The OnMouseUp
method finally is called when a mouse button is released. If the left mouse button is released, the next call to the OnPaint
method will draw the chosen area onto the whole control (zoom).
protected void OnMouseUp(object sender,
System.Windows.Forms.MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
m_blnZoom = true;
this.Refresh();
}
Last but not least, the code that needs to be added to the OnPaint
method. If the control is in �zoom-mode�, the necessary scaling and translation on the Graphics
are executed. After that, all the drawing wanted for the control is done (DrawContents()
). Finally the rectangle for the area to zoom (black rectangle) is drawn. That�s all.
protected void OnPaint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
if (m_blnZoom)
{
e.Graphics.ScaleTransform((float)this.ClientSize.Width/m_ZoomRect.Width,
(float)this.ClientSize.Height/m_ZoomRect.Height);
e.Graphics.TranslateTransform(-m_ZoomRect.X, -m_ZoomRect.Y);
}
DrawContents(e.Graphics);
if (!m_blnZoom)
{
e.Graphics.DrawRectangle(new Pen(new SolidBrush(Color.Black), 2),
m_ZoomRect);
}
}