wpf在精确鼠标位置拖放

时间:2016-10-18 19:24:20

标签: c# wpf canvas

我有一个ListBox和一个Canvas。我想将ListBoxItem拖到Canvas上,正好放置鼠标。这是我的xaml。问题是无论鼠标位置如何,物品都放在另一个上面。如何根据画布上的鼠标指针将拖动的项目放在确切的位置。请帮忙。

<DockPanel LastChildFill="True" >
        <ListBox DockPanel.Dock="Left" Name="lstLabels">
            <ListBox.Resources>
                <Style TargetType="{x:Type ListBoxItem}">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>
                    <EventSetter Event="PreviewMouseMove" Handler="ListBoxItem_PreviewMouseMove"/>

                </Style>
            </ListBox.Resources>
            <ListBoxItem>A</ListBoxItem>
            <ListBoxItem>B</ListBoxItem>
            <ListBoxItem>C</ListBoxItem>
            <ListBoxItem>D</ListBoxItem>
            <ListBoxItem>E</ListBoxItem>
            <ListBoxItem>F</ListBoxItem>
            <ListBoxItem>G</ListBoxItem>
            <ListBoxItem>H</ListBoxItem>
        </ListBox>
        <Canvas AllowDrop="True" Background="Azure"
                DragEnter="cvsSurface_DragEnter" Drop="cvsSurface_Drop" 
                Name="cvsSurface" >
        </Canvas>
    </DockPanel>

这是我完整的cs代码

 private ListBoxItem draggedItem;
 private Point startDragPoint;
private void cvsSurface_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                e.Effects = DragDropEffects.Copy;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }
        }
        private void cvsSurface_Drop(object sender, DragEventArgs e)
        {
            Label newLabel = new Label();
            newLabel.Content = e.Data.GetData(DataFormats.Text);

            cvsSurface.Children.Add(newLabel);
            Canvas.SetLeft(newLabel, 100);
            Canvas.SetTop(newLabel, 200);

            draggedItem = null;
            lstLabels.SelectedItem = null;
        }
        private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            draggedItem = sender as ListBoxItem;
            startDragPoint = e.GetPosition(null);
        }
        private void ListBoxItem_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            Point position = e.GetPosition(null);
            if (draggedItem != null)
            {
                DragDrop.DoDragDrop(draggedItem, draggedItem.Content, DragDropEffects.Copy);
            }
        }

1 个答案:

答案 0 :(得分:0)

检查我的OnDrop处理程序以将位置分配给标签

using System;
using System.Collections.Generic;
using System.Diagnostics;
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 CanvasDragDrop
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private ListBoxItem draggedItem;

        private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            draggedItem = sender as ListBoxItem;

            if (draggedItem != null)
            {
                DragDrop.DoDragDrop(draggedItem, draggedItem.Content, DragDropEffects.Copy);
            }

        }


        private void CvsSurface_OnDragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                e.Effects = DragDropEffects.Copy;
            }
            else
            {
                e.Effects = DragDropEffects.None;
            }

        }

        private void CvsSurface_OnDrop(object sender, DragEventArgs e)
        {
            Object droppedData = e.Data; //This part is not important

        /*Translate Drop Point in reference to Stack Panel*/
            Point dropPoint = e.GetPosition(this.cvsSurface);

            Console.WriteLine(dropPoint); ;
            Label lbl = new Label();
            lbl.Content = draggedItem.Content;
            cvsSurface.Children.Add(lbl);

            Canvas.SetLeft(lbl, dropPoint.X);
            Canvas.SetTop(lbl, dropPoint.Y);

        }



    }
}

此外,您需要更少的活动

<Window x:Class="CanvasDragDrop.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel LastChildFill="True" >
        <ListBox DockPanel.Dock="Left" Name="lstLabels">
            <ListBox.Resources>
                <Style TargetType="{x:Type ListBoxItem}">
                    <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>


                </Style>
            </ListBox.Resources>
            <ListBoxItem>A</ListBoxItem>
            <ListBoxItem>B</ListBoxItem>
            <ListBoxItem>C</ListBoxItem>
            <ListBoxItem>D</ListBoxItem>
            <ListBoxItem>E</ListBoxItem>
            <ListBoxItem>F</ListBoxItem>
            <ListBoxItem>G</ListBoxItem>
            <ListBoxItem>H</ListBoxItem>
        </ListBox>
        <Canvas AllowDrop="True" Background="Azure"
                DragEnter="CvsSurface_OnDragEnter" Drop="CvsSurface_OnDrop" 
                Name="cvsSurface" >
        </Canvas>
    </DockPanel>
</Window>