In Silverlight, the simplest way to implement the drag object function is to use Canvas as the parent container. By dynamically changing the Top and Left attributes of an element, you can achieve the same drag performance. :
See the following example:
XAML:
<UserControl x:Class="DragExample.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="500" d:DesignWidth="600"> <Canvas x:Name="LayoutRoot" Background="Gray"> <Ellipse x:Name="ellipse" Canvas.Left="300" Canvas.Top="300" Width="100" Height="100" Stroke="YellowGreen" Fill="White" StrokeThickness="5" MouseLeftButtonDown="ellipse_MouseLeftButtonDown" MouseMove="ellipse_MouseMove" MouseLeftButtonUp="ellipse_MouseLeftButtonUp"></Ellipse> </Canvas></UserControl>
CS:
Public partial class MainPage: UserControl {public MainPage () {InitializeComponent ();} /// <summary> /// identify whether an object can be dragged /// </summary> private bool isDrag = false; private void ellipse_MouseLeftButtonDown (object sender, MouseButtonEventArgs e) {isDrag = true; ellipse. captureMouse ();} private void ellipse_MouseMove (object sender, MouseEventArgs e) {if (isDrag) {Point position = e. getPosition (LayoutRoot );
// Locate the Canvas by absolute position. setLeft (ellipse, position. x); Canvas. setTop (ellipse, position. y) ;}} private void ellipse_MouseLeftButtonUp (object sender, MouseButtonEventArgs e) {isDrag = false ;}}
Running effect:
By using this method, we can find that the experience is not very realistic. When the mouse pointer moves, it is always in the upper Left corner of the circle, that is, the (Left, Top) coordinates. So how to perfect it so that the mouse is not in any position of the circle, can show the real movement process. You can calculate the relative moving location to solve the problem. Demo diagram:
As follows:
Public partial class MainPage: UserControl {public MainPage () {InitializeComponent ();} /// <summary> /// identify whether the object can be dragged /// </summary> private bool isDrag = false; private Point StartPoint; private Point EndPoint; private void ellipse_MouseLeftButtonDown (object sender, MouseButtonEventArgs e) {isDrag = true; StartPoint = e. getPosition (LayoutRoot); ellipse. captureMouse ();} private void ellipse_MouseMove (object sender, MouseEventArgs e) {if (isDrag) {EndPoint = e. getPosition (LayoutRoot); // calculates the relative offset between the start point of X and y axis and the end point. double y = EndPoint. y-StartPoint. y; double x = EndPoint. x-StartPoint. x; Point position = new Point (double) Canvas. getLeft (ellipse), (double) Canvas. getTop (ellipse); // calculates the position of the target coordinate relative to the (Left, Top) coordinate. X = position. X + x; position. Y = position. Y + y; Canvas. setLeft (ellipse, position. x); Canvas. setTop (ellipse, position. y); StartPoint = EndPoint ;}} private void ellipse_MouseLeftButtonUp (object sender, MouseButtonEventArgs e) {isDrag = false ;}}
Running effect:
The above uses Canvas as the container to implement the element drag function. However, a drawback of using Canvas as the parent container is that child elements cannot be automatically horizontally and vertically centered, A certain amount of mathematical computation and analysis is required to center the circle. If the center of the current circle is the coordinate, the zoom-in and zoom-out function is implemented, instead of using (Left, Top) as the circle to zoom in and out the target point, is there any good solution ??
In the second method, you can dynamically calculate the Left, Top, Right, and Bottom values of Margin to achieve hyperactivity.
Use Grid as the parent container, XAML:
<Grid x:Name="LayoutRoot" Background="Gray"> <Ellipse x:Name="ellipse" Width="100" Height="100" Stroke="YellowGreen" Fill="White" StrokeThickness="5" MouseLeftButtonDown="ellipse_MouseLeftButtonDown" MouseMove="ellipse_MouseMove" MouseLeftButtonUp="ellipse_MouseLeftButtonUp"></Ellipse> </Grid>
CS:
Public partial class MainPage: UserControl {public MainPage () {InitializeComponent ();} /// <summary> /// identify whether the object can be dragged /// </summary> private bool isDrag = false; private Point StartPoint; private Point EndPoint; private void ellipse_MouseLeftButtonDown (object sender, MouseButtonEventArgs e) {isDrag = true; StartPoint = e. getPosition (LayoutRoot); ellipse. captureMouse ();} private void ellipse_MouseMove (object sender, MouseEventArgs e) {if (isDrag) {EndPoint = e. getPosition (LayoutRoot); // calculates the relative offset between the start point of X and y axis and the end point. double y = EndPoint. y-StartPoint. y; double x = EndPoint. x-StartPoint. x; Thickness margin = ellipse. margin; // calculate the new Margin Thickness newMargin = new Thickness () {Left = margin. left + x, Top = margin. top + y, Right = margin. right-x, Bottom = margin. bottom-y}; ellipse. margin = newMargin; StartPoint = EndPoint;} private void ellipse_MouseLeftButtonUp (object sender, MouseButtonEventArgs e) {isDrag = false ;}}
Running effect:
Solution 3: Use the MouseDragElementBehavior of Expression Blend 4 to attach the element to implement free drag. The above is a summary of Silverlight dragging. Are there other solutions?