Click here to Skip to main content
15,885,730 members
Articles / Programming Languages / C#

A .NET Wizard control

Rate me:
Please Sign up or sign in to vote.
4.86/5 (89 votes)
24 Apr 2003CPOL7 min read 660.3K   8.7K   216  
A .NET Wizard control for the VS.IDE and client apps
using System;
using System.Windows.Forms;
using System.Collections;


namespace UtilityLibrary.General
{
	/// <summary>
	/// CustomDragger provides easy way for handling Drag&Drop operations
	/// </summary>
  public class CustomDragger 
  {
    #region Class constants
    // Dragging begins after mouse was moved by DraggerDelay pixels
    private const int DraggerDelay = 3;     
    #endregion

    #region Class Variables
    private int           mouseX;
    private int           mouseY;
    private bool          dragging; 
    protected object      obj;
    private Control       m_parent;
    private Control       m_accepter;
    private bool          buttonDowned;
    #endregion

    #region Internal Classes
    public class DragDropInternal  
    {
      public const int DEF_MEMORY_RESERVE = 16;

      private ArrayList m_dataTypes;
      private ArrayList m_dataValues;


      public DragDropInternal()
      {
        m_dataTypes = new ArrayList( DEF_MEMORY_RESERVE );
        m_dataValues = new ArrayList( DEF_MEMORY_RESERVE );
      }

      public void Add( string type, object value )
      {
        m_dataTypes.Add( type );
        m_dataValues.Add( value );
      }

      public ArrayList listByType (string type)
      {
        ArrayList res = new ArrayList( DEF_MEMORY_RESERVE );
        
        for ( int i = 0; i < m_dataTypes.Count; i++ )
        {
          if ( (string)m_dataTypes[i] == type ) 
          {
            res.Add( m_dataValues[i] );
          }
        }
        
        return res;
      }
      
      public bool isEmpty()
      {
        return ( m_dataTypes.Count == 0 );
      }

      public void Clear()
      {
        m_dataTypes.Clear();
        m_dataValues.Clear();
      }
    }

    
    #region Class Events Arguments wrappers
    public class DataRequestArgs : EventArgs
    {
      private DragDropInternal m_data;
      private int m_x;
      private int m_y;

      public int X
      {
        get{return m_x;}
      }
      public int Y
      {
        get{return m_y;}
      }

      
      public DragDropInternal Data
      {
        get
        {
          return m_data;
        }
      }

      public DataRequestArgs( DragDropInternal data, int X, int Y )
      {
        m_data = data;
        m_x = X;
        m_y = Y;
      }
    }

    public class DropEffectsArgs : EventArgs
    {
      private DragDropEffects m_effects;
      private int m_keyState;
      private int m_x;
      private int m_y;
      private DragDropInternal m_data;

      public int KeyState 
      {
        get
        {
          return m_keyState;
        }
      }

      public int X
      {
        get{return m_x;}
      }
      public int Y
      {
        get{return m_y;}
      }

      public DragDropInternal Data
      {
        get
        {
          return m_data;
        }
      }

      public DragDropEffects Effects
      {
        get
        {
          return m_effects;
        }
        set
        {
          m_effects = value;
        }
      }


      public DropEffectsArgs( DragDropInternal data, DragDropEffects effects, int X, int Y, int keyState )
      {
        m_effects = effects;
        m_x = X;
        m_y = Y;
        m_keyState = keyState;
        m_data = data;
      }
    }
    
    public class DropRequestArgs : EventArgs
    {
      private DragDropInternal m_data;
      private int m_keyState;
      private int m_x;
      private int m_y;

      public int KeyState 
      {
        get
        {
          return m_keyState;
        }
      }

      public int X
      {
        get{return m_x;}
      }
      public int Y
      {
        get{return m_y;}
      }

      public DragDropInternal data
      {
        get
        {
          return m_data;
        }
      }


      public DropRequestArgs( DragDropInternal data, int X, int Y, int keyState )
      {
        m_data = data;
        m_x = X;
        m_y = Y;
        m_keyState = keyState;
      }
    }
    #endregion
    
    #endregion

    #region Class delegates
    public delegate void DataRequestEventHandler( object sender, DataRequestArgs e );
    public delegate void DropEffectsEventHandler( object sender, DropEffectsArgs e );
    public delegate void DropDataEventHandler( object sender, DropRequestArgs e );
    #endregion
    
    #region Class events declaration
    public event DataRequestEventHandler  OnDataRequest;
    public event DropEffectsEventHandler  OnEffectsRequest;
    public event DropDataEventHandler     OnDataDrop;
    #endregion
    
    #region Class constructor
    public CustomDragger( Control parent, Control accepter ) 
    {
      m_parent = parent;
      m_accepter = accepter;
      
      AttachEvents();
    }
    #endregion

    #region Class events attachments
    protected void AttachEvents()
    {
      if( m_parent != null && m_accepter != null )
      {
        m_parent.Disposed   += new EventHandler( OnParentDisposed );
        m_parent.MouseDown  += new MouseEventHandler( MouseDown );
        m_parent.MouseMove  += new MouseEventHandler( MouseMove );
        m_parent.MouseUp    += new MouseEventHandler( MouseUp );
        m_parent.MouseLeave += new EventHandler( MouseLeave );

        m_accepter.Disposed += new EventHandler( OnParentDisposed );
        m_accepter.DragOver += new DragEventHandler( DragOver );
        m_accepter.DragDrop += new DragEventHandler( DragDrop );
      }
    }

    protected void DetachEvents()
    {
      if( m_parent != null && m_accepter != null )
      {
        m_parent.Disposed   -= new EventHandler( OnParentDisposed );
        m_parent.MouseDown  -= new MouseEventHandler( MouseDown );
        m_parent.MouseMove  -= new MouseEventHandler( MouseMove );
        m_parent.MouseUp    -= new MouseEventHandler( MouseUp );
        m_parent.MouseLeave -= new EventHandler( MouseLeave );

        m_accepter.Disposed -= new EventHandler( OnParentDisposed );
        m_accepter.DragOver -= new DragEventHandler( DragOver );
        m_accepter.DragDrop -= new DragEventHandler( DragDrop );
      }
    }
    #endregion
  
    #region Mouse event handlers
    private void OnParentDisposed( object sender, EventArgs e )
    {
      DetachEvents();
    }

    private void BeginDragging ( object sender )
    {
      dragging = true;
      DragDropInternal data = new DragDropInternal();
      
      if( OnDataRequest != null ) 
      {
        System.Drawing.Point point = new System.Drawing.Point ( mouseX, mouseY );
        //point = ((Control)sender).PointToClient(point);
        OnDataRequest( sender, new DataRequestArgs ( data, point.X, point.Y ) );
      }
      
      if( !data.isEmpty() )
      {
        m_parent.DoDragDrop( data, 
          DragDropEffects.All | DragDropEffects.Link | DragDropEffects.Copy | DragDropEffects.Scroll);
      }
    }

    private void MouseMove( object sender, System.Windows.Forms.MouseEventArgs e )
    {
      if( !dragging && e.Button == MouseButtons.Left ) 
      {
        if( Math.Abs(mouseX - e.X) >= DraggerDelay || Math.Abs(mouseY - e.Y) >= DraggerDelay ) 
        {
          BeginDragging( sender );
        }
      }
    }
    
    private void MouseLeave( object sender, EventArgs e )
    {
      if( !dragging && buttonDowned ) 
      {
        BeginDragging( sender );
      }
    }
    
    private void MouseDown( object sender, System.Windows.Forms.MouseEventArgs e )
    {
      buttonDowned = false;
      
      if( e.Button == MouseButtons.Left )
      {
        mouseX = e.X;
        mouseY = e.Y;
        buttonDowned = true;
        dragging = false;
      }
    }

    private void MouseUp( object sender, System.Windows.Forms.MouseEventArgs e )
    {
      buttonDowned = false;
    }
    
    private void DragOver( object sender, System.Windows.Forms.DragEventArgs e )
    {                        
      System.Drawing.Point point = new System.Drawing.Point ( e.X, e.Y );
      point = ( ( Control )sender ).PointToClient( point );
        
      DragDropInternal data = new DragDropInternal();
        
      DropEffectsArgs arg = new DropEffectsArgs( ( DragDropInternal )e.Data.GetData( data.GetType() ), 
        DragDropEffects.Copy, point.X, point.Y, e.KeyState );
        
      if ( OnEffectsRequest != null )
      {
        OnEffectsRequest( sender, arg );
      }
        
      e.Effect = arg.Effects;
    }

    private void DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
    {
      if ( OnDataDrop != null )
      {
        DragDropInternal data = new DragDropInternal();
        
        if ( e.Data.GetDataPresent(data.GetType()) ) 
        {
          System.Drawing.Point point = new System.Drawing.Point ( e.X, e.Y );
          point = ((Control)sender).PointToClient(point);
          
          OnDataDrop( sender, new DropRequestArgs( ( DragDropInternal )e.Data.GetData( data.GetType() ), 
            point.X, point.Y, e.KeyState ) );
        }
      }
    }
    #endregion
  }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
CEO ArtfulBits Inc.
Ukraine Ukraine
Name:Kucherenko Oleksandr

Born:September 20, 1979

Platforms: Win32, Linux; - well known and MS-DOS; Win16; OS/2 - old time not touched;

Hardware: IBM PC

Programming Languages: Assembler (for Intel 80386); Borland C/C++; Borland Pascal; Object Pascal; Borland C++Builder; Delphi; Perl; Java; Visual C++; Visual J++; UML; XML/XSL; C#; VB.NET; T-SQL; PL/SQL; and etc.

Development Environments: MS Visual Studio 2001-2008; MS Visual C++; Borland Delphi; Borland C++Builder; C/C++ any; Rational Rose; GDPro; Together and etc.

Libraries: STL, ATL, WTL, MFC, NuMega Driver Works, VCL; .NET 1.0, 1.1, 2.0, 3.5; and etc.

Technologies: Client/Server; COM; DirectX; DirectX Media; BDE; HTML/DHTML; ActiveX; Java Servlets; DCOM; COM+; ADO; CORBA; .NET; Windows Forms; GDI/GDI+; and etc.

Application Skills: Databases - design and maintain, support, programming; GUI Design; System Programming, Security; Business Software Development. Win/Web Services development and etc.

Comments and Discussions