4

我有一个形式为 UserControl:

<UserControl>   
    <Grid>         
          <!-- Content Here-->    
      <StackPanel>   <!-- I want this element to be draggable within the usercontrol. -->    
         <Label Name = "Header" />  
         <Button />
         <Button />
         <Button />             
         </StackPanel>    
   <Grid>             
</UserControl>

我的最终结果是有一个可以拖动的带有按钮(用户控件的一部分)的控件..?也就是说,在 UserControl 内可移动...

我读过关于拇指的书,但我不知道如何使用它......任何想法或例子都会很棒。谢谢!

4

6 回答 6

11

一个非常简单的方法是使用鼠标事件

首先,将你StackPanel的东西包裹起来,Canvas这样它就可以根据用户拖动它的位置轻松定位

接下来,将MouseDownMouseUp事件添加到StackPanel. 您可能需要为其提供StackPanel背景颜色才能接收鼠标事件。

在这种情况MouseDown下,将MouseMove事件处理程序附加到StackPanel并让面板捕获鼠标,以便所有鼠标事件都将由StackPanel.

MouseUp事件中,分离MouseMove事件并释放鼠标捕获。

在这种情况MouseMove下,根据当前鼠标位置更改面板的Canvas.TopCanvas.Left属性。您需要在此处进行检查以确定鼠标是否在屏幕之外,UserControl因此StackPanel无法将鼠标拖出屏幕。

就是这样,非常基本的拖放:)

于 2012-09-07T16:11:18.393 回答
2

这是 WPF 中 Draggable Rectangle 的实际工作示例,这正是 Rachel 上面所说的。

你可以在标签里面放任何UserControl// etc StackPanelGridCanvas

我这样做是因为我在拖动 a 时遇到了问题StackPanel,问题实际上是我在面板上设置了一个边距,所以它被抵消了。

当您拖动它时,它不会跳过。

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Canvas x:Name="canvas" Background="Transparent" PreviewMouseLeftButtonDown="PreviewDown" PreviewMouseLeftButtonUp="PreviewUp" MouseMove="MoveMouse">
            <Rectangle x:Name="Rectangle" HorizontalAlignment="Left" Fill="Black" Height="85" Margin="0" Stroke="Black" VerticalAlignment="Top" Width="82" />
        </Canvas>
    </Grid>
</Window>

XAML

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private object movingObject;
        private double firstXPos, firstYPos;

        private void PreviewDown(object sender, MouseButtonEventArgs e)
        {
            firstXPos = e.GetPosition(Rectangle).X;
            firstYPos = e.GetPosition(Rectangle).Y;

            movingObject = sender;
        }

        private void PreviewUp(object sender, MouseButtonEventArgs e)
        {
            movingObject = null;
        }

        private void MoveMouse(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed && sender == movingObject)
            {
                double newLeft = e.GetPosition(canvas).X - firstXPos - canvas.Margin.Left;

                Rectangle.SetValue(Canvas.LeftProperty, newLeft);

                double newTop = e.GetPosition(canvas).Y - firstYPos - canvas.Margin.Top;

                Rectangle.SetValue(Canvas.TopProperty, newTop);
            }
        }
    }
}

MainWindow.cs

于 2021-04-30T00:56:16.930 回答
0

一种方法是处理按钮上的鼠标单击并在移动鼠标时更改其位置。

所以步骤将是:

  1. 向按钮添加处理程序。例如鼠标点击(或鼠标按下)
  2. 当您收到鼠标点击时,将处理程序添加到 mousemove。
  3. 检查鼠标的移动并更改按钮的位置
  4. 释放鼠标按钮后删除处理程序。
于 2012-09-07T14:51:27.223 回答
0

我不知道任何具体的方法,但直观地说,您可以添加一个事件处理程序来拖动您想要移动的控件的方法,并且在该方法中,您可以将控件渲染为位图,使该位图跟随您的鼠标指针,并隐藏原始控件。当放下(鼠标释放)时,它应该简单地将原始控件的坐标设置为鼠标坐标,处理位图,并重新启用控件的可见性。

于 2012-09-07T14:51:42.380 回答
0

在 MSDN 和其他地方有一些可用的教程。尝试使用以下链接进行 WPF 拖放。

WPF 拖放

于 2012-09-07T14:54:46.663 回答
0

你应该给avalondock 项目一个机会。

这允许您创建丰富的布局功能,如 Visual Studio 所做的(浮动、停靠等)。

我相信这会对你有所帮助。

于 2012-09-07T14:56:27.097 回答