2

I've an app which like the image shown below (sorry I used an iPhone like mock-ups)

img1

The app has an image as background (displayed using Canvas which takes the whole visual screen size), then another shape (the red rectangle in this case) will shown above the background which can be dragged and pinch zoomed.

Now the question is:

How can I get the coordinates (origins from top-left corner of the screen, i.e. top-left of the canvas) of the top-left corner of the rectangle?


UPDATE

According to @Will's suggestion, I currently move the rectangle in this case via DragDelta using TranslateTransform inside it, like:

rectTransform.X += e.HorizonalChange;
rectTransform.Y += e.VerticalChange;

The rectangle is defined within code, not in XAML:

rect.Stroke = new SolidColorBrush(Colors.Green);
rect.StrokeThickness = 10;
rect.Fill = new SolidColorBrush(Colors.Transparent);
rect.HorizontalAlignment = System.Windows.HorizontalAlignment.Center;
rect.VerticalAlignment = System.Windows.VerticalAlignment.Center;
rect.Width = 200;
rect.Height = 200;

canvas.Children.Add(rect);

and the canvas is defined within XAML.


What I've tried:

Initially I was trying to get the start point when the Drag event begins, but by using the DragStarted(object sender, DragStartedGestureEventArgs e), I am only able to output the coords of the point which was touched, but not the point of top-left corner of this rectangle.

And it's similar to the DragCompleted event which will return me the point the gesture ends.

So is there any chance I can get the origin coords of the red rectangle?

dumbfingers
  • 7,001
  • 5
  • 54
  • 80

2 Answers2

3

I spent nearly an afternoon on Google as well as MSDN and then finally come to find this on SO:

How to get the position of an element in a StackPanel?

which enlightened me using the similar method. In that case, they managed to get the absolute coordinates of an UI Element. Similarily, in my case, I intend to know the absolute origin(coordinates) of the red rectangle to the background canvas.

I use:

GeneralTransform gt = canvas.TransformToVisual(rect);
Point currentPos = gt.Transform(new Point(0, 0));

Then the currentPos is the current position of rectangle (its an absolute position, relative to the canvas).

And Here's the reference of TransformToVisual in MSDN

There's only one thing to pay attention to: the value of X and Y are negative.

Community
  • 1
  • 1
dumbfingers
  • 7,001
  • 5
  • 54
  • 80
0

Not 100% sure of the syntax here, but in WPF (which should be analogous) I'd handle it by

private double _startX, startY, _endX, _endY;
private void DragStarted(object sender, DragStartedGestureEventArgs e)
{
   var rect = sender as UIElement; // I'm assuming the sender is your Rectangle
   this._startX = Canvas.GetLeft(rect);
   this._startY = Canvas.GetTop(rect);
}
private void DragCompleted(object sender, DragCompletedGestureOrWhateverLolEventArgs e)
{
   var rect = sender as UIElement; // I'm assuming the sender is your Rectangle
   this._endX = Canvas.GetLeft(rect);
   this._endY = Canvas.GetTop(rect);
}

What you say? Not type safe? Yeah, well, okay. How about give your rectangle an x:Name and then use that in these methods?

<Rectangle x:Name="rect" SkipOtherPropertiesLol="true" />

and

this._startX = Canvas.GetLeft(rect); //etc

Attached properties are a little confusing at first, but they are very powerful and easy to use once you understand their fairy magic.

  • thx buddy, I'll try it right now. BTW, its `Canvas.GetLeft`, so the returned coords will be the relative to Canvas, am I right? – dumbfingers Jan 16 '13 at 16:52
  • XD sorry for the iPhone at the beginning. But I wonder, Canvas.GetLeft is different from the canvas.GetLeft if I give the background canvas a name "canvas"? – dumbfingers Jan 16 '13 at 16:55
  • @ss1271: Uh, I said `Canvas.GetLeft`. Yeah. The canvas in which the Rectangle is laid out will use that attached property on the instance of your Rectangle to keep track of where it is. So you can use the *static* method `Canvas.GetLeft` passing in your rect to get the current value of that property. –  Jan 16 '13 at 16:56
  • Attached properties are implemented as DependencyProperties with a static `SetXYZ` and `GetXYZ` method on the type that defines them. So you do NOT have to use your instance of the canvas in order to get this property... Only the Canvas that holds your Rect as a child will use this attached property. –  Jan 16 '13 at 16:57
  • Bear me, I always got (0,0) when using `Canvas.GetLeft(rect)` and `Canvas.GetTop(rect)`. The canvas beneath the rectangle has `x:Name="c"`. Is there anything wrong? thx – dumbfingers Jan 16 '13 at 17:01
  • @ss1271: Is the Rect being moved on the canvas, or by a RenderTransform or a LayoutTransform? Try a minimal example of your code--a Canvas, with one Rectangle, that is moved. You might just have a Rectangle rendered *over* a Canvas rather than a Rectangle *within* a canvas, e.g., `` where the Rectangle isn't in the Canvas, its in the Grid. –  Jan 16 '13 at 17:51
  • Its important to understand HOW your rectangle is being moved by the drag code. There are a number of different ways, among which are changing Canvas.Left/Top, transforms, and even by changing margins. Without knowing 1. your xaml and 2. this code, we're just stabbing in the dark. Again, a ***minimal*** example (xaml and code) would probably result in a quick solution. –  Jan 16 '13 at 18:19
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22888/discussion-between-ss1271-and-will) – dumbfingers Jan 17 '13 at 09:08