【问题标题】:Make a StackPanel and its contents "draggable" in wpf?在 wpf 中制作 StackPanel 及其内容“可拖动”?
【发布时间】:2012-09-07 14:47:12
【问题描述】:

我有一个用户控件,格式为:

<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 但我不知道如何使用它...任何想法或示例都会很棒。谢谢!

【问题讨论】:

标签: c# wpf xaml


【解决方案1】:

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

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

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

MouseDown 事件中,将MouseMove 事件处理程序附加到StackPanel 并设置面板capture the mouse,这样所有鼠标事件都将由StackPanel 处理。

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

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

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

【讨论】:

  • 谢谢瑞秋。这真的给了我一个kickstart!
【解决方案2】:

这是 WPF 中 Draggable Rectangle 的实际工作示例,这正是 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

【讨论】:

    【解决方案3】:

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

    所以步骤是:

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        WPF Drag and Drop

        【讨论】:

        • 感谢您的链接...这不完全是拖放,它只是使控件可移动...有点像 Windows DragMove()。
        【解决方案6】:

        你应该给avalondock project一个机会。

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

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

        【讨论】:

          猜你喜欢
          • 2013-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-06-21
          • 2015-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多