Tuesday, February 13, 2007

XAML Window Positioning with Dragging

Many forums have users ask about repositioning a Windows Form application around by means of dragging inside the window. I started seeing more questions about this with regards to XAML projects in Blend and Visual Studio. It can be done very easily with use of a Timer control. If you know of an even simpler way of accomplishing this please let me know.

First you will need to add a reference to the System.Windows.Forms and System.Drawing namespaces. The Drawing namespace would only be required if you want to enable snapping to the edges of your screen. I'll discuss this later though.

Add a timer control with events into the code. You will also need to add two doubles to hold the initial position of your cursor.


 


 

Private
WithEvents DragTimer As Windows.Forms.Timer

Dim initY As
Double

Dim initX As
Double


 

Within the New method, initialize the timer and give it an interval of 5 milliseconds.


 

Public
Sub
New()


MyBase.New()


 


Me.InitializeComponent()


 

DragTimer = New Windows.Forms.Timer

DragTimer.Interval = 5

End
Sub


 

You will need to determine position of the cursor relative to the form. I believe there is a property already out there for this but I don't remember it so just create to functions.


 

Private
Function TopDistance() As
Double


Return (Windows.Forms.Cursor.Position.Y - Me.Window.Top)

End
Function


 

Private
Function LeftDistance() As
Double


Return (Windows.Forms.Cursor.Position.X - Me.Window.Left)

End
Function


 

All that is left now is the two methods needed to handle the main windows MouseUp and MouseDown events and the method to handle the timer's Tick event. The MouseDown event handler will set the initial cursor position values relative to the actual form. It will then turn on the timer. The MouseUp event handler simply turns the timer off. The Tick event will trigger the actual forms location change.


 

Private
Sub Window1_MouseDown(ByVal sender As
Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles
Me.MouseDown

initY = TopDistance()

initX = LeftDistance()


 

DragTimer.Enabled = True

End
Sub


 

Private
Sub Window1_MouseUp(ByVal sender As
Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles
Me.MouseUp

DragTimer.Enabled = False

End
Sub


 

Private
Sub DragTimer_Tick(ByVal sender As
Object, ByVal e As System.EventArgs) Handles DragTimer.Tick


Me.Window.Top = Windows.Forms.Cursor.Position.Y - initY


Me.Window.Left = Windows.Forms.Cursor.Position.X - initX

End
Sub


 

If you have the need to restrain only the movement on the x or y plane, simply remove the corresponding line in the Tick event.

No comments: