8.4 Create a Movable Sprite


Problem

You need to create a shape that the user can manipulate on a form, perhaps by dragging it, resizing, or otherwise interacting with it.

Solution

Create a custom control, and override the painting logic to draw a shape. Assign your shape to the Control.Region property. You can then use this Region to perform hit testing.

Discussion

If you need to create a complex user interface that incorporates many custom- drawn elements, you need a way to track these elements and allow the user to interact with them. The easiest approach in .NET is to create a dedicated control by deriving a class from System.Windows.Forms.Control . You can then customize the way this control is painted in the way its basic set of events is raised.

The following example shows a control that represents a simple ellipse shape on a form. All controls are associated with a rectangular region on a form, so the EllipseShape control generates an ellipse that fills these boundaries (provided through the Control.ClientRectangle property). Once the shape has been generated, the Control.Region property is set according to the bounds on the ellipse. This ensures that events such as MouseMove , MouseDown , Click , and so on will occur only if the mouse is over the ellipse, not the entire client rectangle.

The full EllipseShape code is shown in the following code:

 using System; using System.Windows.Forms; using System.Drawing; using System.Drawing.Drawing2D; public class EllipseShape : System.Windows.Forms.Control {     private GraphicsPath path = null;     private void RefreshPath() {              // Create the GraphicsPath for the shape (in this case         // an ellipse that fits inside the full control area)         // and apply it to the control by setting         // the Region property.         path = new GraphicsPath();         path.AddEllipse(this.ClientRectangle);         this.Region = new Region(path);     }     protected override void OnResize(System.EventArgs e) {              base.OnResize(e);         RefreshPath();         this.Invalidate();     }     protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {              base.OnPaint(e);         if (path != null) {                      e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;             e.Graphics.FillPath(new SolidBrush(this.BackColor), path);             e.Graphics.DrawPath(new Pen(this.ForeColor, 4), path);         }     } } 

You could define the EllipseShape control in a separate class library assembly so that it could be added to the Microsoft Visual Studio .NET Toolbox and used at design time. However, even without taking this step, it's easy to create a simple test application. The following Windows form creates two ellipses and allows the user to drag both of them around the form, simply by holding the mouse down and moving the pointer.

 public class SpriteTest : System.Windows.Forms.Form {     // (Designer code omitted.)     // Tracks when drag mode is on.     private bool isDraggingA = false;     private bool isDraggingB = false;     // The ellipse shape controls.     private EllipseShape ellipseA, ellipseB;     private void SpriteTest_Load(object sender, System.EventArgs e) {              // Create and configure both ellipses.         ellipseA = new EllipseShape();         ellipseA.Width = ellipseA.Height = 100;         ellipseA.Top = ellipseA.Left = 30;         ellipseA.BackColor = Color.Red;         this.Controls.Add(ellipseA);         ellipseB = new EllipseShape();         ellipseB.Width = ellipseB.Height = 100;         ellipseB.Top = ellipseB.Left = 130;         ellipseB.BackColor = Color.Azure;         this.Controls.Add(ellipseB);         // Attach both ellipses to the same set of event handlers.         ellipseA.MouseDown += new MouseEventHandler(Ellipse_MouseDown);         ellipseA.MouseUp += new MouseEventHandler(Ellipse_MouseUp);         ellipseA.MouseMove += new MouseEventHandler(Ellipse_MouseMove);         ellipseB.MouseDown += new MouseEventHandler(Ellipse_MouseDown);         ellipseB.MouseUp += new MouseEventHandler(Ellipse_MouseUp);         ellipseB.MouseMove += new MouseEventHandler(Ellipse_MouseMove);     }     private void Ellipse_MouseDown(object sender, MouseEventArgs e) {              // Get the ellipse that triggered this event.         Control control = (Control)sender;         if (e.Button == MouseButtons.Left) {                      control.Tag = new Point(e.X, e.Y);             if (control == ellipseA) {                 isDraggingA = true;             }else {                 isDraggingB = true;             }         }     }     private void Ellipse_MouseUp(object sender, MouseEventArgs e) {              isDraggingA = false;         isDraggingB = false;     }     private void Ellipse_MouseMove(object sender, MouseEventArgs e) {              // Get the ellipse that triggered this event.         Control control = (Control)sender;         if ((isDraggingA && control == ellipseA)           (isDraggingB && control == ellipseB)) {                      // Get the offset.             Point point = (Point)control.Tag;             // Move the control.             control.Left = e.X + control.Left - point.X;             control.Top = e.Y + control.Top - point.Y;         }     } } 

Figure 8.4 shows the user about to drag an ellipse.


Figure 8.4: Dragging custom shape controls on a form.



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net