Drag and Drop for Board Games

Environment: W2K, VS.NET

This application shows how the drag and drop features in C# could be used to create a simple board game or whatever. I didn't put any type of game in the application in order to keep the source code simple. The application just lets you move the dots around the board. It allows highlighting a tile when you drag over it, doesn't allow dragging onto a tile with a dot, and the cursor changes depending on whether or not you can drop the dot.

Code

There are two classes in this project: smDragDropTest and smTile.

smDragDropTest inherits from System.Windows.Forms.Form and is used for the main form. In order to allow the drag and drop to register properly you must mark your main with [STAThread] if that isn't there it will throw an exception.

public class smDragDropTest : 
                System.Windows.Forms.Form

smTile inherits from System.Windows.Forms.PictureBox and is used for the board tiles

public class smTile : 
           System.Windows.Forms.PictureBox

smDragDropTest dynamically creates the smTiles on the form to create a board.

// Initialize the grid
grid = new smTile[MAX_GRID_SIZE, MAX_GRID_SIZE];

// Initialize each tile in the grid
for (int row = 0; row < MAX_GRID_SIZE; row++) {

  for (int col = 0; col < MAX_GRID_SIZE; col++) {

    try {
      // Create the tile
      grid[row,col] = new smTile();

      // Set the location for the tile
      xSpot = (col * IMAGE_WIDTH) + BORDER_OFFSET;
      ySpot = (row * IMAGE_HEIGHT) + BORDER_OFFSET;
      grid[row,col].Location = new Point(xSpot, ySpot);

      // Add the tile to the form
      this.Controls.Add(grid[row,col]);
    }
    catch {
      // Just catch an exception, no error handling yet
      System.Console.WriteLine(
      "Exception caught for tile[{0}, {1}]", 
      row, col);
    }
  }
}

The smTile constructor loads the images and sets up the event handlers. We are going to handle the mouse down, drag enter, drag leave, and drag drop events. In order for an object to allow dragging you must set the AllowDrop property to true. To see what each event handler does you can look at the code, it is pretty straight forward.

filledImage = new System.Drawing.Bitmap("dotBox.jpg");
emptyImage = new System.Drawing.Bitmap("emptyBox.jpg");
overImage = new System.Drawing.Bitmap("overBox.jpg");

this.MouseDown += new MouseEventHandler(OnMouseDown);
this.DragEnter += new DragEventHandler(OnDragEnter);
this.DragDrop += new DragEventHandler(OnDragDrop);
this.DragLeave += new EventHandler(OnDragLeave);
this.AllowDrop = true;

To start the dragging process we use the OnMouseDown event. All you have to do is call DoDragDrop.

public void OnMouseDown( object sender, 
                         MouseEventArgs e)   
{
  // Only allowing dragging if there is an item
  if (hasItem) {

    // Start the dragging process
    DragDropEffects effect = DoDragDrop( this.Image,
	                             DragDropEffects.Copy);

    // Check to see if the image was dropped somewhere
    if (effect != DragDropEffects.None) {

      // It was dropped so remove the item
      RemoveItem();
    }			
  }
}

In order to use custom cursors and not the default drag and drop cursors you must override OnGiveFeedback. Once you do that it is your job to change the cursors when you need to.

protected override void OnGiveFeedback( 
                     GiveFeedbackEventArgs gfbEvent)
{
  // Allow us to use our own cursors when dragging
  gfbEvent.UseDefaultCursors = false;			
};

In OnDragEnter we check to see if the correct data is being dragged into the box by using the GetDataPresent(DataFormats.Bitmap) from the DragEventArgs. If it is the right kind of data we set the Effect property of DragEventArgs to whatever effect you want.  In this case we are dragging around Bitmaps and allowing them to be copied.  Since we handle the images ourselves we don't really care about the data, we are just using it for a place holder to give use the drag and drop functionality.

// Check to see if we can handle what is being dragged
if (e.Data.GetDataPresent(DataFormats.Bitmap)) {

  // Change the cursor to a hand
  this.Cursor = Cursors.Hand;

  // Lets it know what effects can be done
  e.Effect = DragDropEffects.Copy;

  // Change the image
  this.Image = overImage;
}

Well that is about it. Hopefully someone finds it helpful.

Downloads

Download demo project & source- 31 Kb


Comments

  • Thanks

    Posted by apskallen on 12/13/2004 10:42am

    It's not very new or complicated, but it solved a major problem for me. Thanks!

    Reply
  • Drag and drop for board games in Visual C++

    Posted by Legacy on 05/09/2002 12:00am

    Originally posted by: Soheer

    Hi,

    Does anyone have a GUI written in Visual C++ for dragging and dropping buttons? For example like a checkers board where I can drag and drop the pucks and also be able to click on them?
    Any help would be much appreciated,

    Thanks

    (email: schoudhr@hotmail.com)

    Reply
  • Shouldn't use standard data type

    Posted by Legacy on 03/04/2002 12:00am

    Originally posted by: Gavin Lambert

    If you're going to ignore the passed-in data and handle everything internally, you shouldn't use a standard data-type like Bitmap.

    If you do that, it's possible for someone to drag a bitmap from another application onto your program and seriously confuse it. You should use a custom datatype instead, or actually use the incoming bitmap data.

    Reply
  • error when load form

    Posted by Legacy on 01/24/2002 12:00am

    Originally posted by: ErosLin

    can not found .resx when load the form of the smDragDropTest

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • On-demand Event Event Date: July 22, 2014 In this WhatWorks analysis, John Pescatore examines a use case where end users had local administrative rights on their PCs and it had gotten out of hand for this Fortune 500 Energy and Utilities company. The compelling event that prompted the company to reexamine this situation was the migration to Windows 7. In Windows XP, a custom tool that allowed users one of three levels of administrative rights to their workstations would need to be replaced during the Windows …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds