在wpf中拖放用户控件 [英] Drag and drop user controls in wpf

查看:74
本文介绍了在wpf中拖放用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

我用谷歌搜索了如何在wpf中以相同的形式拖放用户控件,但没有得到任何完美的控件.

我在wpf表单中有3个usercontrols.
我想将这些用户控件以相同的形式拖放到画布上.
我是WPF的新手,并与这些mousemove,mouseleftbuttondown和其他事件处理程序混淆.

在这些事件处理程序中到底要写什么.如何在drop eventhandler中创建和捕获数据对象.

任何人都可以通过一个很好的例子帮助我.plz为我提供源代码,以便我理解.


谢谢,

Hello,

i googled to check how to drag and drop usercontrols in the same form in wpf but didnt get any perfect one.

i have 3 usercontrols in the wpf form.
i want to drag and drop these usercontrols on a canvas in the same form.
Iam new to WPF and confused with these mousemove, mouseleftbuttondown,and other event handlers.

what exactly to write in these eventhandlers. how can be dataobject created and captured in drop eventhandler.

can any one help me out with a good example.plz provide me the source code so that i can understand.


thanks,

推荐答案

我的另一个解决方案"实现了一个usercontrol,可以将其拖动到最初放置在同一画布上.

如果您需要将用户控件从画布"上的另一个元素拖动,那么这里是使用WPF拖放的示例...

首先,实现一个自定义的Canvas类(它是放置目标)和一个拖放数据类,以将信息从拖放源传递到放置目标:
My other "solution" implements a usercontrol which can be dragged around the same canvas it''s originally placed on.

If you meant you need to drag the user controls from another element on TO a Canvas, then here''s an example using WPF drag and drop...

First, implement a custom Canvas class which is a drop target and a drag/drop data class to pass info from the drag/drop source to the drop target:
public class DropableCanvas : Canvas
{
    public DropableCanvas()
        : base()
    {
        this.AllowDrop = true;
        this.Drop += new DragEventHandler(DropableCanvas_Drop);
    }

    void DropableCanvas_Drop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(DropableCanvasDragDropData)))
        {
            DropableCanvasDragDropData dragdropdata = e.Data.GetData(typeof(DropableCanvasDragDropData)) as DropableCanvasDragDropData;

            // Remove usercontrol from its starting panel
            dragdropdata.SourcePanel.Children.Remove(dragdropdata.UserControl);

            // Position the usercontrol on this canvas at the drop point
            Point dropPoint = e.GetPosition(this);
            Canvas.SetLeft(dragdropdata.UserControl, dropPoint.X - dragdropdata.OffsetPoint.X);
            Canvas.SetTop(dragdropdata.UserControl, dropPoint.Y - dragdropdata.OffsetPoint.Y);

            // Add the usercontrol to this canvas
            this.Children.Add(dragdropdata.UserControl);
        }
        e.Handled = true;
    }
}

public class DropableCanvasDragDropData
{
    public DropableCanvasDragDropData(Panel srcpanel, UserControl control, Point pt)
    {
        this.SourcePanel = srcpanel;
        this.UserControl = control;
        this.OffsetPoint = pt;
    }

    public Panel SourcePanel { get; protected set; }
    public UserControl UserControl { get; protected set; }
    public Point OffsetPoint { get; protected set; }
}


接下来,通过使其成为拖动源来实现可拖动的用户控件:


Next,implement a dragable user control by making it a drag source:

public partial class DragableUserControl : UserControl
{
    public DragableUserControl()
    {
        InitializeComponent();
    }

    private void UserControl_MouseMove(object sender, MouseEventArgs e)
    {
        DragableUserControl dragableusercontrol = sender as DragableUserControl;
        if (dragableusercontrol != null && e.LeftButton == MouseButtonState.Pressed)
        {
            DragDrop.DoDragDrop(dragableusercontrol,
                            new DropableCanvasDragDropData(dragableusercontrol.Parent as Panel, dragableusercontrol, e.GetPosition(dragableusercontrol)),
                            DragDropEffects.All);
        }
    }
}


<UserControl x:Class="WPFTester.DragableUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             MouseMove="UserControl_MouseMove"
             >
    <Grid Width="100" Height="100" >
        <Border Background="SteelBlue" />
    </Grid>
</UserControl>


最后,全部测试:


And finally, test it all:

<UserControl x:Class="WPFTester.DragControlTestPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFTester"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="450"
             >
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <local:DropableCanvas Grid.Column="0" Background="LightSteelBlue" Height="200" Width="200" Margin="10" >
            <local:DragableUserControl Canvas.Left="10" Canvas.Top="10" />
        </local:DropableCanvas>
        <local:DropableCanvas Grid.Column="1" Background="LightSteelBlue" Height="200" Width="200" Margin="10" >
            <local:DragableUserControl Canvas.Left="10" Canvas.Top="10" />
        </local:DropableCanvas>
    </Grid>
</UserControl>


您应该能够在两个画布之间拖放两个可拖动的用户控件.

*编辑* 2011年7月5日从DragableUserControl类... oops中删除了几个未使用的字段.

*编辑* 2011年7月6日这是一个删除与拖动的用户控件类型相同的新用户控件而不是移动拖动的控件的示例.只需将DropableCanvas.DropableCanvas_Drop方法更改为此:


You should be able to drag and drop the two dragable usercontrols between the two canvases.

*Edit* 7/5/2011 Removed a couple unused fields from the DragableUserControl class...oops.

*Edit* 7/6/2011 Here''s an example of dropping a new usercontrol of the same type as the dragged usercontrol instead of moving the dragged control. Just change the DropableCanvas.DropableCanvas_Drop method to this:

void DropableCanvas_Drop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(DropableCanvasDragDropData)))
    {
        DropableCanvasDragDropData dragdropdata = e.Data.GetData(typeof(DropableCanvasDragDropData)) as DropableCanvasDragDropData;

        //// Remove usercontrol from its starting panel
        //dragdropdata.SourcePanel.Children.Remove(dragdropdata.UserControl);

        // Make a new usercontrol to drop
        UserControl newcontrol;
        try
        {
            newcontrol = Activator.CreateInstance(dragdropdata.UserControl.GetType()) as UserControl;
        }
        catch (Exception)
        {
            //**TODO** Handle this! For now, silent fail.
            newcontrol = null;
        }

        if (newcontrol != null)
        {
            // Position the usercontrol on this canvas at the drop point
            Point dropPoint = e.GetPosition(this);
            Canvas.SetLeft(newcontrol, dropPoint.X - dragdropdata.OffsetPoint.X);
            Canvas.SetTop(newcontrol, dropPoint.Y - dragdropdata.OffsetPoint.Y);

            // Add the usercontrol to this canvas
            this.Children.Add(newcontrol);
        }
    }
    e.Handled = true;
}


还是从一开始就开始....学习WPF基础知识...

Windows Presentation Foundation [
Or start from the very very beginning....learning WPF fundamentals...

Windows Presentation Foundation[^]

Here''s a simple example of a usercontrol that can be dragged on a canvas...
public partial class DragableUserControl : UserControl
{
    public DragableUserControl()
    {
        InitializeComponent();
    }

    bool inDrag = false;
    Point anchorPoint;

    private void UserControl_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (!inDrag)
        {
            anchorPoint = e.GetPosition(null);
            CaptureMouse();
            inDrag = true;
            e.Handled = true;
        }
    }

    private void UserControl_MouseMove(object sender, MouseEventArgs e)
    {
        if (inDrag)
        {
            Point currentPoint = e.GetPosition(null);
            Canvas.SetLeft(this, Canvas.GetLeft(this) + (currentPoint.X - anchorPoint.X));
            Canvas.SetTop(this, Canvas.GetTop(this) + (currentPoint.Y - anchorPoint.Y));
            anchorPoint = currentPoint;
            e.Handled = true;
        }
    }

    private void UserControl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (inDrag)
        {
            ReleaseMouseCapture();
            inDrag = false;
            e.Handled = true;
        }
    }
}

<UserControl x:Class="WPFTester.DragableUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             MouseLeftButtonDown="UserControl_MouseLeftButtonDown"
             MouseMove="UserControl_MouseMove"
             MouseLeftButtonUp="UserControl_MouseLeftButtonUp"
             >
    <Grid Width="100" Height="100" >
        <Border Background="SteelBlue" />
    </Grid>
</UserControl>



*编辑* 这是测试可拖动用户控件的示例...



*Edit* Here''s an example to test the dragable usercontrol...

<UserControl x:Class="WPFTester.DragControlTestPage"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WPFTester"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             Height="300" Width="300" >
    <Grid >
        <Canvas Background="LightSteelBlue" >
            <local:DragableUserControl Canvas.Left="10" Canvas.Top="10" />
        </Canvas>
    </Grid>
</UserControl>


也许您遇到了问题,因为您正试图找到完全适合您情况的解决方案.这不是一个非常有成果的方法,因为每个设计都有其独特的功能.因此,也许所有开发人员都可以解决他们自己的问题并分享结果,但是没人可以确切地解决您的问题.在这种情况下,您需要从基础开始.

您没有在报告任何特定问题,只需问一下如何编写该问题即可.这是众所周知的,并且有文档记录,与其他WPF方面的文档可能含糊不清.

我认为不乏有关该主题的文档.从一开始就开始:
http://msdn.microsoft.com/en-us/library/ms742859. aspx [ ^ ].

—SA
Perhaps you face a problem because you''re trying to find the solution fitting your case exactly. This is not a very fruitful way because each design has its unique features; so perhaps all developers solve their own problem and share the result, no one may be solving exact your problem. In such cases, you need to start with basics.

You''re not reporting any particular problem, just ask how to write this and that. This is all well known and documented, not like some other WPF aspects which can be documented obscurely.

I think there is no lack of documentation on the topic. Start from the very beginning: http://msdn.microsoft.com/en-us/library/ms742859.aspx[^].

—SA


这篇关于在wpf中拖放用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆