Check out a short video below XAML code. It shows what compiled XAML looks like and demostrates dragging and resizing.
* * * * * * * * * * * * *
* Here's the XAML code: *
* * * * * * * * * * * * *
<Window x:Class="MoveObjectOnMouseDownUpMove.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Canvas x:Name="canvas" MouseMove="Canvas_MouseMove">
<Border Name="border1" Canvas.Left="123" Canvas.Top="35"
BorderBrush="DarkKhaki" BorderThickness="1" CornerRadius="5" Padding="5"
Height="68" Width="68" MinHeight="10" MinWidth="10"
MouseLeftButtonDown="border_MouseLeftButtonDown"
MouseLeave="border_MouseLeave"
MouseEnter="border_MouseEnter">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="DarkGray"/>
</Border.BitmapEffect>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Rectangle x:Name="rect" Fill="DarkKhaki" RadiusX="5" RadiusY="5"/>
</Border>
<Border Name="border2" Canvas.Left="123" Canvas.Top="35"
BorderBrush="DarkKhaki" BorderThickness="1" CornerRadius="5" Padding="5"
Height="68" Width="68" MinHeight="10" MinWidth="10"
MouseLeftButtonDown="border_MouseLeftButtonDown"
MouseLeave="border_MouseLeave"
MouseEnter="border_MouseEnter">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="DarkGray"/>
</Border.BitmapEffect>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Rectangle x:Name="rect" Fill="DarkKhaki" RadiusX="5" RadiusY="5"/>
</Border>
<Border Name="border3" Canvas.Left="123" Canvas.Top="35"
BorderBrush="DarkKhaki" BorderThickness="1" CornerRadius="5" Padding="5"
Height="68" Width="68" MinHeight="10" MinWidth="10"
MouseLeftButtonDown="border_MouseLeftButtonDown"
MouseLeave="border_MouseLeave"
MouseEnter="border_MouseEnter">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="DarkGray"/>
</Border.BitmapEffect>
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Rectangle x:Name="rect" Fill="DarkKhaki" RadiusX="5" RadiusY="5"/>
</Border>
</Canvas>
</Window>
When you compile XAML Code, it will look the image below. Before starting to go into C# file to add logic to the events created in XAML, check out the video to see the dragging, resizing and maintaining of the z Order.
* * * * * * * * * * * * * * * * * * *
Here's the C# code
* * * * * * * * * * * * * * * * * * *
end of post
public partial class Window1 : Window
{
private Element current = new Element();
public Window1()
{
InitializeComponent();
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
this.current.X = Mouse.GetPosition(this.canvas).X;
this.current.Y = Mouse.GetPosition(this.canvas).Y;
if(this.current.InputElement != null)
this.current.InputElement.CaptureMouse();
if (!this.current.IsStretching)
this.current.IsDragging = true;
}
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonUp(e);
if (this.current.InputElement != null)
this.current.InputElement.ReleaseMouseCapture();
this.Cursor = Cursors.Arrow;
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if ( e.LeftButton == MouseButtonState.Pressed &&
current.InputElement != null)
{
//increment z-Order and pass it to the current element,
//so that it stays on top of all other elements
((Border)this.current.InputElement).SetValue(Canvas.ZIndexProperty, this.current.ZIndex++);
if (this.current.IsDragging)
Drag(sender);
if (this.current.IsStretching)
Stretch(sender);
}
}
private void border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
//capture the last highest z index before pointing to new current element
int newZIndex = (int)((Border)sender).GetValue(Canvas.ZIndexProperty);
this.current.ZIndex = newZIndex > this.current.ZIndex ? newZIndex : this.current.ZIndex;
//capture the new current element
this.current.InputElement = (IInputElement)sender;
}
private void border_MouseLeave(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
return;
// get coordinates
Border border = (Border)sender;
var rightLimit = border.ActualWidth - border.Padding.Right;
var bottomLimit = border.ActualHeight - border.Padding.Bottom;
var x = Mouse.GetPosition((IInputElement)sender).X;
var y = Mouse.GetPosition((IInputElement)sender).Y;
// figure out stretching directions - only to Right, Bottom
bool stretchRight = (x >= rightLimit && x < border.ActualWidth) ? true : false;
bool stretchBottom = (y >= bottomLimit && y < border.ActualHeight) ? true : false;
// update current element
this.current.InputElement = (IInputElement)sender;
this.current.X = x;
this.current.Y = y;
this.current.IsStretching = true;
//set cursor to show stretch direction
if (stretchRight && stretchBottom)
{
this.Cursor = Cursors.SizeNWSE;
return;
}
else if (stretchRight && !stretchBottom)
{
this.Cursor = Cursors.SizeWE;
return;
}
else if (stretchBottom && !stretchRight)
{
this.Cursor = Cursors.SizeNS;
return;
}
else //no stretch
{
this.Cursor = Cursors.Arrow;
this.current.IsStretching = false;
}
}
private void border_MouseEnter(object sender, MouseEventArgs e)
{
Border border = (Border)sender;
var rightLimit = border.ActualWidth - border.Padding.Right;
var bottomLimit = border.ActualHeight - border.Padding.Bottom;
var x = Mouse.GetPosition((IInputElement)sender).X;
var y = Mouse.GetPosition((IInputElement)sender).Y;
if (x < rightLimit && y < bottomLimit)
this.Cursor = Cursors.Arrow;
}
private void Drag(object sender)
{
this.Cursor = Cursors.Hand;
// Retrieve the current position of the mouse.
var newX = Mouse.GetPosition((IInputElement)sender).X;
var newY = Mouse.GetPosition((IInputElement)sender).Y;
// Reset the location of the object (add to sender's renderTransform newPosition minus currentElement's position
var transformGroup = ((UIElement)this.current.InputElement).RenderTransform as TransformGroup;
if (transformGroup == null)
return;
var translateTransforms = from transform in transformGroup.Children
where transform.GetType().Name == "TranslateTransform"
select transform;
foreach (TranslateTransform tt in translateTransforms)
{
tt.X += newX - current.X;
tt.Y += newY - current.Y;
}
// Update the beginning position of the mouse
current.X = newX;
current.Y = newY;
}
private void Stretch(object sender)
{
// Retrieve the current position of the mouse.
var mousePosX = Mouse.GetPosition((IInputElement)sender).X;
var mousePosY = Mouse.GetPosition((IInputElement)sender).Y;
//get coordinates
Border border = (Border)this.current.InputElement;
var xDiff = mousePosX - this.current.X;
var yDiff = mousePosY - this.current.Y;
var width = ((Border)this.current.InputElement).Width;
var heigth = ((Border)this.current.InputElement).Height;
//make sure not to resize to negative width or heigth
xDiff = (border.Width + xDiff) > border.MinWidth ? xDiff : border.MinWidth;
yDiff = (border.Height + yDiff) > border.MinHeight ? yDiff : border.MinHeight;
// stretchRight && stretchBottom ?
if (this.Cursor == Cursors.SizeNWSE)
{
((Border)this.current.InputElement).Width += xDiff;
((Border)this.current.InputElement).Height += yDiff;
}
// stretchRight ?
else if (this.Cursor == Cursors.SizeWE)
((Border)this.current.InputElement).Width += xDiff;
// stretchBottom ?
else if (this.Cursor == Cursors.SizeNS)
((Border)this.current.InputElement).Height += yDiff;
//no stretch
else
{
this.Cursor = Cursors.Arrow;
this.current.IsStretching = false;
}
// update current coordinates with the latest postion of the mouse
this.current.X = mousePosX;
this.current.Y = mousePosY;
}
}
public class Element
{
#region Fields
private bool isDragging = false;
private bool isStretching = false;
private bool stretchLeft = false;
private bool stretchRight = false;
private IInputElement inputElement = null;
private double x, y = 0;
private int zIndex = 0;
#endregion
#region Constructor
public Element(){}
#endregion
#region Properties
public IInputElement InputElement
{
get { return this.inputElement; }
set
{
this.inputElement = value;
this.isDragging = false;
this.isStretching = false;
}
}
public double X
{
get { return this.x; }
set { this.x = value; }
}
public double Y
{
get { return this.y; }
set { this.y = value; }
}
public int ZIndex
{
get { return this.zIndex; }
set { this.zIndex = value; }
}
public bool IsDragging
{
get { return this.isDragging; }
set
{
this.isDragging = value;
this.isStretching = !this.isDragging;
}
}
public bool IsStretching
{
get { return this.isStretching; }
set
{
this.isStretching = value;
this.IsDragging = !this.isStretching;
}
}
public bool StretchLeft
{
get { return this.stretchLeft; }
set { this.stretchLeft = value; this.stretchRight = !this.stretchLeft; }
}
public bool StretchRight
{
get { return this.stretchRight; }
set { this.stretchRight = value; this.stretchLeft = !this.stretchRight; }
}
#endregion
}
}
_________________________________________________________________