在WPF中制作可移动控件

发布于 2024-09-01 15:47:16 字数 117 浏览 7 评论 0原文

我有一个面板,该面板内有几个矩形控件(控件的数量不同),我希望用户能够在面板内移动控件,以便他们可以以最适合他们的方式排列控件。有没有人有任何我可以阅读的资源或简单的提示,可以帮助我走上正确的道路?

谢谢

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柒夜笙歌凉 2024-09-08 15:47:16

我想出了一种以拖动/移动方式移动控件的可能的简单方法...以下是步骤。

  1. 在控件中选择一个您希望作为移动区域的元素。如果用户按住鼠标,控件将在该区域中移动。就我而言,它是控件顶部的矩形边框。
  2. 使用 OnMouseDown 事件将布尔值(在我的例子中为 IsMoving)设置为 true,并使用 MouseUp 事件将其设置为 false
  3. 在第一个 MouseDown 事件上,使用以下代码设置一些 Point 属性 (InitialPosition)

    if(第一次点击)
    {
         GeneralTransform 变换 = this.TransformToAncestor(this.Parent as Visual);
         点 StartPoint = transform.Transform(new Point(0, 0));
         起始X = 起始点.X;
         起始Y = 起始点.Y;
         第一次点击=假;
    }
    
  4. 现在您已经有了起始位置,您需要获取鼠标相对于移动控件的位置。这样您就不必最终单击标题的中间来移动它,它会立即将控件的左上角移动到鼠标指针位置。为此,请将此代码放置在 MouseDown 事件中:

    PointrelativeMousePoint = Mouse.GetPosition(Header);
    相对 X = 相对鼠标点.X;
    相对Y = 相对鼠标点.Y;
    
  5. 现在您已经有了控件的起始点(startX 和 STartY),即鼠标在移动控件中的位置(RelativeX、RelativeY),我们只需移动控制到一个新的位置!执行此操作需要执行几个步骤。首先,您的控件需要有一个 RenderTransform,它是一个 TranslateTransform。如果您不想在 XAML 中设置它,请随意使用 this.RenderTransform = new TranslateTransform 进行设置。

  6. 现在我们需要在 RenderTransform 上设置 X 和 Y 坐标,以便控件移动到新位置。以下代码完成此任务

    private void Header_MouseMove(对象发送者,MouseEventArgs e)
    {
        如果(正在移动)
        {
            //获取鼠标相对于父控件的位置              
            点 MousePoint = Mouse.GetPosition(this.Parent as IInputElement );
            //设置距原位置的距离
            this.DistanceFromStartX= MousePoint.X - StartX -relativeX ;
            this.DistanceFromStartY= MousePoint.Y - StartY -relativeY;
            //将RenderTransform的X和Y坐标设置为距原始位置的距离。这将移动控制
            TranslateTransform MoveTransform = base.RenderTransform as TranslateTransform;
            MoveTransform.X = this.DistanceFromStartX;
            MoveTransform.Y = this.DistanceFromStartY;
        }
    }
    

正如你可以猜到的,有一些代码被遗漏了(变量声明等),但这应该是你开始所需的全部:)快乐的编码。

编辑:
您可能遇到的一个问题是,这允许您将控件移出其父控件的区域。下面是一些快速但肮脏的代码来解决该问题...

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;
}

在实际移动发生之前将此代码放入 MouseMove 事件中。这将检查控件是否试图移出父控件的边界。 IsMoving = false 命令将导致控件退出移动模式。这意味着用户需要再次单击移动区域才能尝试移动控件,因为控件将停在边界处。如果您希望控件自动继续移动,只需将该行取出,一旦光标回到合法区域,控件就会跳回到光标上。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文