tags:

views:

247

answers:

3

Hi guys,

I have a panel, within that panel are several rectangular controls (the number of controls vaires) I want the user to be able to move the controls around within the panel so that they can arrange the controls in the way that suits them best. does anyone have any resources i could read or simple tips which would get me headed down the right road?

thanks

+2  A: 

Hey,

I figured out a possible, simple method of moving a control in a drag/move style... Here are the steps.

  1. Select an element in your control which you wish to be the movement area. This is the area in which, if me user holds the mouse down, the control will move. In my case it was a rectangular border at the top of the control.
  2. Use the OnMouseDown event to set a boolean (in my case IsMoving) to true and the MouseUp event to set it to false
  3. On the first MouseDown event, set some Point property (InitialPosition) using the following code

    if (FirstClick)
    {
         GeneralTransform transform = this.TransformToAncestor(this.Parent as Visual);
         Point StartPoint = transform.Transform(new Point(0, 0));
         StartX = StartPoint.X;
         StartY = StartPoint.Y;
         FirstClick = false;
    }
    
  4. Now that you have the starting position, you need to get the position of the mouse relative to your movement control. This is so you dont end up clicking the middle of your header to move it and it instantly moves the top left of the control to the mouse pointer location. To do this, place this code in the MouseDown event:

    Point RelativeMousePoint = Mouse.GetPosition(Header);
    RelativeX = RelativeMousePoint.X;
    RelativeY = RelativeMousePoint.Y;
    
  5. Now you have the point the control originated at (startX and STartY), the position of the mouse within your movement control (RelativeX, RelativeY), we just need to move the control to a new location! There are a few steps involved in doing this. Firstly your control needs to have a RenderTransform which is a TranslateTransform. If you dont want to set this in XAML, feel free to set it using this.RenderTransform = new TranslateTransform.

  6. Now we need to set the X and Y coordinates on the RenderTransform so that the control will move to a new location. The following code accomplishes this

    private void Header_MouseMove(object sender, MouseEventArgs e)
    {
        if (IsMoving)
        {
            //Get the position of the mouse relative to the controls parent              
            Point MousePoint = Mouse.GetPosition(this.Parent as IInputElement );
            //set the distance from the original position
            this.DistanceFromStartX= MousePoint.X - StartX - RelativeX ;
            this.DistanceFromStartY= MousePoint.Y - StartY - RelativeY;
            //Set the X and Y coordinates of the RenderTransform to be the Distance from original position. This will move the control
            TranslateTransform MoveTransform = base.RenderTransform as TranslateTransform;
            MoveTransform.X = this.DistanceFromStartX;
            MoveTransform.Y = this.DistanceFromStartY;
        }
    }
    

As you can guess, there is a bit of code left off(variable declarations etc) but this should be all you need to get you started :) happy coding.

EDIT:
One problem you may encounter is that this allows you to move the control out of the area of its parent control. Here is some quick and dirty code to fix that issue...

if ((MousePoint.X + this.Width - RelativeX > Parent.ActualWidth) ||
     MousePoint.Y + this.Height - RelativeY > Parent.ActualHeight ||
     MousePoint.X - RelativeX  < 0 || 
     MousePoint.Y - RelativeY  < 0)
{
    IsMoving = false;
    return;
}

Place this code in your MouseMove event before the actual movement takes place. This will check if the control is trying to move outside the bounds of the parent control. The IsMoving = false command will cause the control to exit movement mode. This means that the user will need to click the movement area again to try to move the control as it will have stopped at the boundary. If you want the control to automatically continue movement, just take that line out and the control will jump back onto the cursor as soon as it is back in a legal area.

TerrorAustralis
As an aside note, if the user moves the mouse to fast, the control will lose movement focus.
TerrorAustralis
A: 

You can find a lot of inspiration here:

http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part1.aspx

http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part2.aspx

http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part3.aspx

http://www.codeproject.com/KB/WPF/WPFDiagramDesigner_Part4.aspx

bretik
There is indeed much inspiration to be had there. It is not exactly what im after but i dont want to accept my answer and this helped me refactor my code a fair bit :)
TerrorAustralis
A: 

Hy, I tried to put up TerrorAustralis's solution but I couldn't make it work. I would like if you(TerrorAustralis) could send me some more "bounded" code on may mail iovan_alexandru at hotmail.comm related to this subject, I would be very greatful to you. I need these feature very much in my project. Thank you for understanding.

Alex