WinForm拖拽控件生成副本的解决方法

By | 10月16日
Advertisement

本文讲述了WinForm中实现拖拽效果的功能,即在WinForm中有一个Button,可以实现拖拽这个Button到目标位置后生成一个该控件的副本的功能。具体操作步骤如下:

要实现该功能主要分成如下三步:

1)确定被拖拽的对象:这里是Button(要使得Button被单击之后可以拖拽,那么必须处理其MouseDown事件,同时调用其DoDragDrop——该函数接受两个参数:i)要拖动的数据。ii)拖动的效果(该效果是2“目标位置”所能够接受的效果,是一个枚举值):

C#代码如下:

Button1.DoDragDrop(Button1, DragDropEffects.Copy || DragDropEffects.Move); //形成拖拽效果,移动+拷贝的组合效果

VB.NET页面代码如下:

Button1.DoDragDrop(Button1, DragDropEffects.Copy Or DragDropEffects.Move)  '形成拖拽效果,移动+拷贝的组合效果

2)目标位置:这里是Form窗体自身。为了使得和Windows资源管理器中实现的文件拖拽效果一样(即拖拽一个文件到目标位置的中途,鼠标出现“+”号的效果)。那么应当处理DragEnter事件——即拖拽控件途中进入Form体内把效果设置成Copy的效果。

C#代码如下:

private void Form1_DragEnter(System.Object sender, System.Windows.Forms.DragEventArgs e)
{
  //当Button被拖拽到WinForm上时候,鼠标效果出现
  if ((e.Data.GetDataPresent(typeof(Button)))) {
    e.Effect = DragDropEffects.Copy;
  }
}

VB.NET页面代码如下:

Private Sub Form1_DragEnter(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter
    If (e.Data.GetDataPresent(GetType(Button))) Then  '当Button被拖拽到WinForm上时候,鼠标效果出现
      e.Effect = DragDropEffects.Copy
    End If
  End Sub

同时,为了使得Form自身支持接受拖拽传来的控件,必须设置其AllowDrag=True:

另外,一旦松开鼠标,那么拖拽过程结束。此时应当处理DragDrop事件,复制一个按钮:

C#代码如下:

private void Form1_DragDrop(System.Object sender, System.Windows.Forms.DragEventArgs e)
{
  //拖放完毕之后,自动生成新控件
  Button btn = new Button();
  btn.Size = Button1.Size;
  btn.Location = this.PointToClient(new Point(e.X, e.Y));
  //用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
  this.Controls.Add(btn);
  btn.Text = "按钮" + count.ToString;
  count = count + 1;
}

VB.NET页面代码如下:

Private Sub Form1_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
    '拖放完毕之后,自动生成新控件
    Dim btn As New Button
    btn.Size = Button1.Size
    btn.Location = Me.PointToClient(New Point(e.X, e.Y))  '用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
    Me.Controls.Add(btn)
    btn.Text = "按钮" + count.ToString
    count = count + 1
  End Sub

这里需要注意点:Location属性(指定控件放置位置的起始点)不能直接用e.X或e.Y——因为这是屏幕坐标,要根据实际的控件界面坐标进行适度转换,最简单方法是——PointToClient方法。

下面给出完整代码:

【界面如下所示】

WinForm拖拽控件生成副本的解决方法

C#代码如下:

using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
public class Form1
{

  //计数变量,说明输出了第N个Button

  private int count = 1;
  private void Form1_Load(System.Object sender, System.EventArgs e)
  {
    this.AllowDrop = true;
    //窗体自身支持接受拖拽来的控件
  }

  private void Button1_MouseDown(System.Object sender, System.Windows.Forms.MouseEventArgs e)
  {
    //左键的话,标志位为true(表示拖拽开始)
    if ((e.Button == System.Windows.Forms.MouseButtons.Left)) {
      Button1.DoDragDrop(Button1, DragDropEffects.Copy | DragDropEffects.Move);
      //形成拖拽效果,移动+拷贝的组合效果
    }
  }

  private void Form1_DragEnter(System.Object sender, System.Windows.Forms.DragEventArgs e)
  {
    //当Button被拖拽到WinForm上时候,鼠标效果出现
    if ((e.Data.GetDataPresent(typeof(Button)))) {
      e.Effect = DragDropEffects.Copy;
    }
  }

  private void Form1_DragDrop(System.Object sender, System.Windows.Forms.DragEventArgs e)
  {
    //拖放完毕之后,自动生成新控件
    Button btn = new Button();
    btn.Size = Button1.Size;
    btn.Location = this.PointToClient(new Point(e.X, e.Y));
    //用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
    this.Controls.Add(btn);
    btn.Text = "按钮" + count.ToString();
    count = count + 1;
  }
  public Form1()
  {
    DragDrop += Form1_DragDrop;
    DragEnter += Form1_DragEnter;
    Load += Form1_Load;
  }
}

VB.NET页面代码如下:

Public Class Form1

  '计数变量,说明输出了第N个Button
  Private count As Integer = 1

  Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Me.AllowDrop = True   '窗体自身支持接受拖拽来的控件
  End Sub

  Private Sub Button1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles Button1.MouseDown
    '左键的话,标志位为true(表示拖拽开始)
    If (e.Button = Windows.Forms.MouseButtons.Left) Then
      Button1.DoDragDrop(Button1, DragDropEffects.Copy Or DragDropEffects.Move)  '形成拖拽效果,移动+拷贝的组合效果
    End If
  End Sub

  Private Sub Form1_DragEnter(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragEnter
    If (e.Data.GetDataPresent(GetType(Button))) Then  '当Button被拖拽到WinForm上时候,鼠标效果出现
      e.Effect = DragDropEffects.Copy
    End If
  End Sub

  Private Sub Form1_DragDrop(sender As System.Object, e As System.Windows.Forms.DragEventArgs) Handles MyBase.DragDrop
    '拖放完毕之后,自动生成新控件
    Dim btn As New Button
    btn.Size = Button1.Size
    btn.Location = Me.PointToClient(New Point(e.X, e.Y))  '用这个方法计算出客户端容器界面的X,Y坐标。否则直接使用X,Y是屏幕坐标
    Me.Controls.Add(btn)
    btn.Text = "按钮" + count.ToString
    count = count + 1
  End Sub
End Class

Similar Posts:

  • Silverlight 游戏开发:可重用的拖拽控件

    游戏中有各种各样的拖拽需求,大到窗口,小到图标,在游戏界面操作中,点击和拖拽占据了用户操作的大部分行为,如何做好一个拖拽控件至关重要,做一个可重用的拖拽控件更加重要,我的这些实现方法可能比较另类,但只要有效就行,在这个基础上,你可以扩展很多的做法. 可能有朋友已经写了这方面的文章,但是本篇介绍的方法是一个可以一劳永逸的重用控件,只需要一个基类代码就可以完成所有的需求--图标.窗体.自定义的目标,所以,本片没有放在小技巧里而是游戏开发分类里. 最先,需要了解一下拖拽原理,即当鼠标按下做一个标识,在

  • 仿扇贝单词----自定义可拖拽控件

    仿扇贝单词--自定义可拖拽控件 最近在做项目时需要实现一个可以拖动的控件,用于在有限的屏幕内显示更多的内容.先给大家看一下效果图. 这个效果的主要特点有以下几点: 1.只有按住拖拽的按钮时才可以拖动,下面的内容布局无法拖动. 2.内容布局的触摸事件处理.判断当前的点击位置是否在拖拽控件内,如果在则消耗掉该事件,反之则传递到内部. 1.首先是布局 <?xml version="1.0" encoding="utf-8"?> <FrameLayout

  • .net中实现拖拽控件

    .net中实现拖拽控件 private int tX = 0; private int tY = 0; private void btn_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { this.tX = e.X; this.tY = e.Y; this.btn.MouseMove += new System.Windows.Forms.MouseEventHandler(this.btn_MouseMove);

  • 多线程访问winform控件出现异常的解决方法

    一. 多线程访问winform控件出现异常的解决方法 1. 问题描述 <1> 如果创建某控件的线程之外的其他线程试图调用该控件,则会引发一个 InvalidOperationException异常. (1) 并提示消息:"从不是创建控件 control name 的线程访问它." <2> 默认情况下,winform控件只能由创建该控件的线程调用 . (1) 如果要在新的线程中调用该控件,则需要使用控件的invoke方法来进行. *****************

  • VS中丢失ArcGis 控件和模板的解决方法

    VS中丢失ArcGis 控件和模板的解决方法 VS中丢失ArcGis 控件和模板的解决方法(看了网上一些方法,多多少少对解决问题有些帮助,集合大家的成果),以下大部分问题是因为先装vs 后装 ArcGis或AE出现.所有这些问题其实都可以通过在装好vs 的基础上重装ArcGis来解决,但是,如果你不想重装的话,可以试试下面的方法. 问题一:工具箱中没有 ArcGis Windows Forms 解决方法: 解法一: 第一步:添加选项卡,命名为ArcGis Windows Forms或者其他你喜欢

  • 手势和UI控件之间冲突的解决方法(比如UITapGesture和UIButton冲突,UIPanGesture和UISlider冲突)

    手势和UI控件之间冲突的解决方法(比如UITapGesture和UIButton冲突,UIPanGesture和UISlider冲突) 作者 xiaoyao Li 在 12 十二月 2012, 5:03 下午 经过实验发现iOS5和iOS6里面,轻点手势和按钮的点击冲突机制是不同的,结果如下: 一个UIView上如果添加了一个按钮,又添加了Tap手势 在iOS5的设备上跑会只响应Tap手势,按钮不响应点击事件,只会有higlighted效果 在iOS5的设备上跑,按住了按钮,当过了3,4秒左右,

  • 有时候拖在storyboard上的控件不见了,解决方法!

    前段时间画了一个很复杂的页面,页面上有很多的控件.放了几天没有打开,然后有一天需要继续完成下去, 一打开发现storyboard上面的控件都不见了,当时呀弄得我一头雾水.后来还是解决了嘛,且看下边: 当时用的是Xcode7.3,打开storyboard是这样的: 问题呢就是因为我用了autolayout和sizeclass.所以呀解决方法就是选回最开始的设备横竖横竖状态. 例:点击界面下方的wAny hAny文字选择选回最开始的设备横竖状态:点击后弹出一个九宫格浮框,拖动鼠标即可选择响应的siz

  • IE加载ocx时提示控件不安全的解决方法

    之前编写的ocx控件在ie浏览器加载的时候,会出现一个提示. 这是因为ocx控件有一个ID,而这个ID注册后IE并没有认为它是安全的控件. 我们必须把这个控件注册为安全控件. 新建的mfc Activity项目有三个重要的类,xxApp,xxCtrl,xxPropPage三个类. 1.在xxApp类头文件添加如下函数声明: HRESULT CreateComponentCategory(CATID catid, WCHAR* catDescription); // Helper function

  • 第一次用.net2.0 LOGIN登陆控件的困惑和解决方法。

    1.我们没有真正的服务器,我们只是租用了.net2.0 + SQLserver空间,SQL数据库名是固定的. 2.空间提供商不可能给我们设定数据源或给你aspnetdb数据库权限. 3.我们没有服务器的 WindowsMicrosoft.NetFrameworkv2.xConfig 权限. 已知上面三点,如果直接把本地测试好的项目传到服务器肯定会出错(因为他默认是调用WindowsMicrosoft.NetFrameworkv2.xConfig ),我认为好的解决方法是把aspnetdb数据库内

  • VS2015使用小技巧 winform编辑窗体(拖拽控件)的的时候,工具箱挡住了窗体,如何解决

    镇场诗:慈心积善融学习,技术誓为大家学.善心速造多好事,前人栽树后乘凉.我今于此写经验,愿见文者得启发. ---------------------------------------------------------- 1.挡住了 2.点击这个 小按钮 3.效果展示 写代码的时候,再点一次那个小按钮.工具箱就消失了. ---------------------------------------------------------- 感恩帮助过我的人.博客的精髓在技术部分,更在镇场一诗. 写

Tags: