Introduction
Everything started in a Microsoft Event where I was able to view the Coolness of the Digg Sample when this was neither on the web and Silverlight beta 1 and beta 2 were coming.
I personally believe that RIA (Rich Internet Applications) is becoming the Windows on the Web, and these are the reasons why:
- In Silverlight, you are working on the Client Environment and don't have postbacks.
- In Silverlight, you can animate the user interaction like a WPF application.
- In Silverlight, you can create a control that is customizable by Application Styles, I know this sounds like CSS but it goes to a different level.
Using the Code
The Drag Control is a Control based from the User Control that provides the user the ability to forget about setting the Mouse Capture events in his code.
public class DragControl : UserControl
{
private bool _isMouseDown;
private Point _lastPosition;
int zIndex = 0;
Note the Extra variables that will help you on the events since we don't want to redo everything over and over especially if we don't need it. Then you will need the events of the Mouse, on the Mouse Down you should be able to detect it and place your control on top of any other control, I've used a BringToFront()
method that will help me perform this action.
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
_isMouseDown = true;
BringToFront();
this.CaptureMouse();
_lastPosition = e.GetPosition(Application.Current.RootVisual);
base.OnMouseLeftButtonDown(e);
}
Now that we have the Button Down, we need the Up event. This is pretty easy since we just need to say stop here and not continue any action.
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
_isMouseDown = false;
zIndex = 0;
this.ReleaseMouseCapture();
base.OnMouseLeftButtonUp(e);
}
And finally we will need the MouseMouse
event. This is the one that handles the motion of the control.
protected override void OnMouseMove(MouseEventArgs e)
{
if (_isMouseDown)
{
Point currentPosition = e.GetPosition(Application.Current.RootVisual);
Canvas.SetLeft(this, currentPosition.X);
Canvas.SetTop(this, currentPosition.Y);
_lastPosition = currentPosition;
}
base.OnMouseMove(e);
}
Also important is our BringToFront()
function that will help you give that Windows functionality when you click to bring to front. Please note that my Main Control is a Canvas, this is why I convert the Parent as Canvas.
protected void BringToFront()
{
if (zIndex == 0)
{
var oldIndex = this.zIndex;
var mainCanvas = this.Parent as Canvas;
foreach (FrameworkElement fElement in mainCanvas.Children)
{
Canvas.SetZIndex(fElement, 0);
}
Canvas.SetZIndex(this, 2);
zIndex = 1;
}
Points of Interest
You will find that the BringtoFront
method will let you do the work only if the Parent is a Canvas. The funny part is that if you are using Stack Panels or Grid, then you will have to do this work.
The canvas is the perfect example since this allows to position controls using left and top attributes.
Note: Due to some reason when compiling for the first time, VS2008 generates the code behind (file name with extension .g.cs). Please make sure you do change the base class declared here in order to make it work.
History
- 25th October, 2008: Initial post