Saturday, October 6, 2012

Silverlight hittest an object is inside a Grid boundary

Silverlight hittest an object is inside a Grid boundary

I have created a draggable control that want to restrict to the boundaries of it's containing grid (i.e. not let the user drag it outside of the grid).

I need a test that returns true or false so that I can cancel the drag if necessary.

I have looked at VisualTreeHelper.FindElementsInHostCoordinates and TransformToVisual etc, but I cannot find a simple way of doing it without lots of checks for each of the corners of the control.

e.g. some code (Dialog is the name of the control that is being dragged):

MouseEventHandler mouseMove = (s, args) =>         {             var transform = new TranslateTransform();             transform.X = args.GetPosition(Dialog).X - _mouseDownPosition.X;             transform.Y = args.GetPosition(Dialog).Y - _mouseDownPosition.Y;              if (transformGroup != null)             {                 transformGroup.Children.Add(transform);                 Dialog.RenderTransform = transformGroup;             }          }; 

Answers & Comments...

Answer: 1

This is no way other than checking each corner of the control.

However, you can take some shortcuts as you know that Dialog and what you are dragging it over won't change shape or size during the drag and that it's impossible for the left hand edge of Dialog to be to the right of the right hand edge of Grid without the right hand edge of Dialog also being to the right of Grid. This only applies if Dialog is not rotated.

So, you'll need something like the following pseudo code:

if (Dialog.Left >= Grid.Left &&     Dialog.Top >= Grid.Top &&     Dialog.Right <= Grid.Right &&     Dialog.Bottom <= Grid.Bottom) {     // Allow the drag } else {     // Snap Dialog to the edge of Grid } 
by : ChrisFhttp://stackoverflow.com/users/59303

Answer: 2

Thanks. In the end I took another approach; instead of trying to stop the user from dragging ANY of the child control outside of the boundary of the container I have only stopped them from dragging the pointer outside the boundary, e.g. in the mousemove eventhandler:

if ((args.GetPosition(parentGrid).X < 0 || args.GetPosition(parentGrid).Y < 0)) {     return; // don't do a translatetransform } 

The problem with this was that the parts of the child control were visible outside of the container.

What I did was set the Clip property of the parent control so that the parts of the child outside of the boundary are hidden.

e.g.:

var clipRegion = new RectangleGeometry(); clipRegion.Rect = new Rect(0, 0, elementParent.ActualWidth, elementParent.ActualHeight); elementParent.SetValue(Canvas.ClipProperty, clipRegion); 

This seems to work quite nicely!

by : Silverfoxhttp://stackoverflow.com/users/440422




No comments:

Post a Comment

Send us your comment related to the topic mentioned on the blog