In this tutorial, we will create two new components, one deriving from Control, the other deriving from UserControl, that both include the possibility to initiate drag-and-drop.
  • Let's create a new project in Visual Studio, name it MyDragDrop.
  • Create a User Control (name it MyUserControl.cs) and a custom control (name it MyControl.cs) and - if you wish - add some fancy code to display something within the control (but this is not the point of this tutorial.)
  • Edit the code of those two files, and add the partial keyword to the class definitions, otherwise you won't be able to mix additional code from another source code file.

MyControl.cs:
namespace MyDragDrop
{
    public partial class MyControl : Control
    {
    }
}
  • Create the Mixin template. By convention, mixin template files end in Mixin.cs. At first, don't put any code in the class. Note that here also you need to use the partial keyword.

DragAndDropMixin.cs:
namespace MyDragDrop
{
    public partial class DragAndDropMixin
    {
    }
}
  • Add two (empty for now) code files to the project : MyUserControl.Mixin.DragAndDrop.cs and MyControl.Mixin.DragAndDrop.cs.
  • Copy Myxin.exe to the project directory, and execute it. Notice that now our two code files were replaced by copies of the mixin file, with the class name changed. Notice also that we did not have to configure anything... From the name MyUserControl.Mixin.DragAndDrop.cs, Myxin knows that it must include DragAndDropMixin.cs and rename the class to MyUserControl.
  • You can compile your project to see that it works (and does nothing)
  • Now it's time to intercept the OnMouseDown event in our mixin class. Unfortunately, you have to know what to type, because Intellisense will not work : our DragAndDropMixin class does not derive from a base class that has a virtual method OnMouseDown. And also, the source code will not compile, for exactly the same reason. We absolutely need to make DragAndDropMixin to derive from a class that already has an OnMouseDown virtual method.
    • We cannot simply add a derivation from Control into the DragAndDropMixin.cs, since that would be copied into all our target implementation files, and produce compilation errors there.
    • However, we can use the fact that since DragAndDropMixin.cs defines the class as partial, we can add another source code file that will not be copied in the target class. By convention, this file ends in .Glue.cs :

DragAndDropMixin.Glue.cs:
namespace MyDragDrop
{
    public partial class DragAndDropMixin : Control
    {
    }
}
  • We can now go back to the DragAndDropMixin.cs file, and type override to see Intellisense jump into action. Our DragDropMixin.cs file now looks like:

DragDropMixin.cs:
namespace MyDragDrop
{
    public partial class DragAndDropMixin
    {
        protected override void OnMouseDown (System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseDown (e);
            DoDragDrop (this, DragDropEffects.All);
        }
    }
}
  • Rerun the myxin.exe tool into the source directory. Both MyControl.Mixin.DragAndDrop.cs and MyUserControl.Mixin.DragAndDrop.cs now contain the appropriate code to intercept MouseDown.
  • Build the project.
  • We now have a project with classes MyControl and MyUserControl that implement drag and drop...

Further down the road

You can do many more things that will be covered later:
  • In your project, go to the properties of files DragAndDropMixin.cs and DragAndDropMixin.Glue.cs and mark their build action as None instead of Compile so they won't be includd in the executable
  • You can define an interface for your added functionality, effectively simulating multiple inheritance.
  • And much more...

Last edited Jan 9, 2010 at 6:12 PM by sleclercq, version 10

Comments

No comments yet.