在Wpf中使StackPanel及其内容“可拖动”?

时间:2012-09-07 14:47:12

标签: c# wpf xaml

我有以下形式的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中可移动......

我读过关于Thumb但我不确定如何使用它......任何想法或例子都会很棒。谢谢!

6 个答案:

答案 0 :(得分:10)

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

首先,将StackPanel包裹在Canvas中,以便根据用户拖动它的位置轻松定位

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

MouseDown事件中,将MouseMove事件处理程序附加到StackPanel并使面板capture the mouse,以便所有鼠标事件都由{{1}处理}。

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

MouseMove事件中,根据当前鼠标位置更改面板的MouseMoveCanvas.Top属性。您需要在此处检查以确定鼠标是否在Canvas.Left之外,以便UserControl无法从屏幕上拖出。

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

答案 1 :(得分:2)

这是 WPF 中可拖动矩形的实际工作示例,这正是 Rachel 上面所说的。

您可以将任何 UserControl/StackPanel/Grid 等放在 Canvas 标签内。

我这样做是因为我在拖动 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

答案 2 :(得分:0)

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

所以步骤将是:

  1. 为按钮添加处理程序。 Mouseclick例如(或mousedown)
  2. 当您收到鼠标点击时,请向mousemove添加处理程序。
  3. 检查鼠标的移动并更改按钮的位置
  4. 释放鼠标按钮后删除处理程序。

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

WPF Drag and Drop

答案 5 :(得分:0)

您应该有机会avalondock project

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

我相信这会对你有帮助。