Canvas.GetTop not updated after Element drag - wpf

I have a Rectangle nested within a Canvas. The rectangle has a MouseDragElementBehavior attached to it, so it can move freely in the canvas.
I need to calculate the position of the rectangle after each drag. The problem is that the
Canvas.GetTop(rectangle1)
only works for the first time, i.e. before the rectangle is dragged. After the drag, the method call returns the initial position.

Those behaviors usually work by applying a RenderTransform, if it uses a TranslateTransform you can get the offset value from that and add it to the canvas position.
Alternatively you might just want to implement your own dragging logic.

Related

Aligning components with each other in WPF

A WPF application consists of a uniform grid of arbitrary size. Each cell in the grid contains a canvas. Each canvas is a target for a drag and drop operation.
When I drag another canvas and drop it onto a canvas inside the grid I want the top left corners of the dragged canvas(source) and the target canvas to align, essentially placing the source on top of the target. The behaviour I'm looking for is a snap-to-grid effect.
Currently when I use element.GetValue(Canvas.LeftProperty) the result in NaN. The problem is to determine the position of the corner for a canvas inside the grid, but relative to the entire window. I would prefer to use the grid, as it automatically resize as the window resize.
Is it possible to get the actual position of a canvas inside a grid even when the grid size changed or alternatively specify a canvas to be aligned to another canvas inside the grid?
This problem was solved by drawing each canvas onto another canvas by specifying the top and left properties of the canvas, I had to scratch the grid. I specified the position of every canvas by using
Canvas.SetLeft(Me, position.X)
Canvas.SetTop(Me, position.Y)
where Me is an instance of the canvas.
It is now easy to get the top and left properties of every canvas. The only problem now is I have to implement the resizing of every canvas manually.

The right event to detect a moving UIElement inside a Canvas

I have a Rectangle within a Canvas. The rectangle has the MouseDragElementBehavior attached to it, so it can move freely within the canvas.
I need to do certain calculations when the smallest changes happen in the position of the rectangle, but i can not find a single best event.
So far I have resorted to MouseMove event for the rectangle which is an overkill. Any alternative?
You should base on the events from MouseDragElementBehaviour class, DragBegun, DragFinished and Draggging.

scrollviewer and canvas - scrolling view to given position

I have some problems with implementing autoscrolling in WPF (I think I could call it that way).
I have a canvas placed inside a scrollviwer. On my canvas I can dynamicly add different shapes. The position of this shapes can be changed with mouse. Everytime I add new shape on canvas or change position of shape I fire measureOverride function.Thanks to this scrollview "know" the real size of canvas and the scrollbars appear. However even if scrolbars appear, the view doesn't "follow" shape which I currently move. I mean if I reach visible part of canvas I would like canvas to srcoll.
I was trying to use this function
ScrollToHorizontalOffset()
However I have problem with proper use of that function. I was trying to use (as a parameter) canvas actualwidth but it didn't work well. I also was trying to use as a parameter current position of shape (which I move) but it works only one way. I the viewer follow the moving element if I was moving this element to right side of canvas. However if I move shape back(to the left) the view don't follow the shape.
I hope somebody will understand this :) It is hard to explain my problem.
I also was trying to use as a
parameter current position of shape
That is the correct way to implement. Waht you need is a converter, which will returns the position according to the direction you move the object.

Silverlight Drag and Drop (without a Canvas)

I'm trying to drag and drop (slide) a Silverlight element from one part of a window to another.
I've implemented the MouseLeftButtonDown, MouseMove, and MouseLeftButtonUp event handlers on the element, but I've run into a bit of a problem.
All of the examples I've seen involve moving the element by setting the Canvas.Left and Canvas.Top properties. None of the elements I'm trying to manipulate live inside a Canvas. Is there a way to set the absolute position of the element being dragged, based on the coordinates of the mouse? Or is there a prepackaged solution to this problems somewhere that I've missed?
All panels but Canvas use some kind of constraint to position their children. Only Canvas lets you use absolute positioning. That's why I think it is the only way to implement drag and drop .
Feel free to use a Canvas on top of your existing panel. Just remember to remove the dragged element from its original parent and put it in the Canvas (or drag some kind of copy) and do the reverse on mouse up.
One way of achieving absolutely positioning an item inside any container, not only Canvas, is to use transformation instead of Left/Top properties. For instance, to set at Left=50 Top=80 you can modify the margin values through transformation.

Silverlight MouseDragElementBehavior. How to rearrange items after drag and drop?

I have stack panel with custom controls in it. User can add or remove the items.
I have attached MouseDragElementBehavior to each item. So now user can move them within the stack panel.
However the items now are arranged on arbitrary manner. Is a mess really. They stay where the user left them.
What I need now is to make them to be stacked as the stack panel supposed to be... Nicely one by one...
So I need to simply let user change the order of items by using drag / drop operation but items has to be stacked precisely.
There is DragFinished event, but I dont really see how the Behavior moves items. I thought it is Margin it changes but margins stays 0... I dont know what to do next.
Appreciate little help.
MouseDragElementBehavior does its work using a Transform on the RenderTransform property of the attached element (i.e. the one the behavior is applied to) (the exact type of transform depends on the state of the RenderTransform property but it will either be a TranslateTransform or a MatrixTransform).
The transform is not reset when you finish dragging (nor would you want it to be because the element would snap back to its position in the StackPanel when you started dragging) and this is why the element stays where "the user left them".
To change the items position in the StackPanel in the way you are talking about you will have to use the DragFinished event. What you probably want to do is work out where in the StackPanel the element will end up (as a result of the drag, i.e. which element in the panel it will "push" down) then create an animation to animate the element from its current position (where the user released the drag) to that final position in the StackPanel and another animation to move the "pushed" element in to its new position in the StackPanel (VisualTreeHelper can probably help here (I think)). Once those animations are finished just set the new index within the StackPanel for each item and remove the RenderTransform translation.

Resources