zoukankan      html  css  js  c++  java
  • C# Winform 涉及的拖放操作总结

    C# Winform 涉及的拖放操作总结

     

    在开发程序的时候,为了提高用户的使用体验,或满足相关用户的功能,总是离不开拖放功能。而本文是总结winform下的常用拖放操作。主要有

    1.textbox接受拖放的文件
    2.listbox允许用户自定义排序
    3.listbox之间的拖放
    4.控件的拖放
    5.console的拖放问题

    用户在进行拖放操作时,经过的步骤大体如下:
    例如将A中的数据拖放的B中
    鼠标点击A中的数据(MouseDown)->鼠标移动(MouseMove)->出源数据边界,即出A(DragLeave)->进入目标边界,进入B(DragEnter)->在B中移动,选择放数据的位置,即拖动效果(DragOver)->抬起鼠标(MouseDown)->将A数据放到B中,拖放结束。(DragDrop,所有的拖放都涉及DragDrop事件)。

    下面的所有例子,都会使用到上面所列举的几个事件。

    一、textbox接受拖放的文件。为了方便用户的使用,这个应该是最常用到的操作。加入这个功能,可以使用户省去“打开文件对话框,然后选择文件”的操作。在这个例子中,我们不需要知道用户的点击,即选择了什么文件。只需要了解用户拖动文件进入Textbox(DragEnter),并松开鼠标,完成拖放(DragDrop)。主要涉及到两个事件。

    DragEnter:在将对象拖入控件的边界时发生。判断是否是文件拖放

    DragDrop:在完成拖放操作时发生。判断文件类型,只添加txt文件

    首先添加一个textBox控件,将控件的属性设置为AllowDrop=True,Multiline=True
    代码如下:

    复制代码
    private void textBox1_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.FileDrop))
        {
            e.Effect = DragDropEffects.Copy;
        }
    }
    
    private void textBox1_DragDrop(object sender, DragEventArgs e)
    {
        string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
        foreach (string file in files)
        {
            if(Path.GetExtension(file)==".txt")  //判断文件类型,只接受txt文件
            {
                textBox1.Text += file + "
    ";
            }
        }
                    
    }
    复制代码

    二、listbox允许用户自定义排序。在一个listbox中的拖放操作,我们要知道用户选择了什么数据(MouseDown),要把数据放到哪里,即坐标(DragOver),完成拖放(DragDrop)。主要涉及的事件有3个
    MouseDown:选择Listbox中的item
    DragOver: 鼠标的移动
    DragDrop: 拖放完成。在鼠标当前位置插入数据

    首先在窗体上加入Listbox控件,将AllowDrop属性设置为True
    代码如下:

    复制代码
    private void FrmListboxDragTest_Load(object sender, EventArgs e)
    {
        for (int i = 0; i <= 20; i++)
        {
            this.listBox1.Items.Add(string.Format("事件{0}",i));
        }
    }
    
    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (this.listBox1.SelectedItem == null)
        {
            return;
        }
        //开始拖放操作,DragDropEffects为枚举类型。
        //DragDropEffects.Move 为将源数据移动到目标数据
        this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);  
    }
    
    private void listBox1_DragOver(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.Move;
    }
    
    private void listBox1_DragDrop(object sender, DragEventArgs e)
    {
        Point point = listBox1.PointToClient(new Point(e.X, e.Y));
        int index = this.listBox1.IndexFromPoint(point);
        if (index < 0)
        {
            index = this.listBox1.Items.Count - 1;
        }
        //获取拖放的数据内容
        object data = e.Data.GetData(typeof(string));
        //删除元数据
        this.listBox1.Items.Remove(data);
        //插入目标数据
        this.listBox1.Items.Insert(index, data);
    }
    复制代码

    三.listbox之间的拖放。因为是在Listbox之间拖放数据,所以涉及到两个控件。假如本例是将Listbox1中的数据拖放到Listbox2中。那涉及的事件有4个
    Listbox1 中的MouseDown:选取Listbox1中的数据
    Listbox2 中的DragEnter:拖放操作进入Listbox2
    Listbox2 中的DragOver: 在Listbox2上移动
    Listbox2 中的DragDrop: 拖放完毕,在Listbox2中显示数据

    代码如下:

    复制代码
    private void FrmTwoListboxDragTest_Load(object sender, EventArgs e)
    {
        for (int i = 0; i <= 20; i++)
        {
            this.listBox1.Items.Add(string.Format("listbox1中的数据{0}", i));
            this.listBox2.Items.Add(string.Format("listbox2中的数据{0}", i));
        }
    }
    
    private void listBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (listBox1.Items.Count == 0)
            return;
    
        int index = listBox1.IndexFromPoint(e.X, e.Y);
        string s = listBox1.Items[index].ToString();
        listBox1.DoDragDrop(s, DragDropEffects.Copy);
    }
    
    private void listBox2_DragEnter(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(DataFormats.StringFormat))
            e.Effect = DragDropEffects.Copy;
    }
    
    private void listBox2_DragOver(object sender, DragEventArgs e)
    {
        e.Effect = DragDropEffects.All;
    }
    
    private void listBox2_DragDrop(object sender, DragEventArgs e)
    {
        Point point = listBox2.PointToClient(new Point(e.X, e.Y));
        int index = this.listBox1.IndexFromPoint(point);
        if (index < 0)
        {
            index = this.listBox1.Items.Count - 1;
        }
        object data = e.Data.GetData(typeof(string));
        this.listBox1.Items.Remove(data);
        this.listBox2.Items.Insert(index, data);
    }
    复制代码

    4.控件的拖放。以pictureBox为例。涉及的事件有
    MouseDown 选取pictureBox,可以判断鼠标按键(左键还是右键等)
    MouseMove 移动鼠标到指定位置
    MouseUp 释放鼠标按键,放下pictureBox

    在进行控件移动的时候,需要明白pictureBox的坐标并不是鼠标的坐标,MouseDown只是在鼠标按下后执行一次,而MouseMove随着pictureBox的移动而不停的触发。

    代码如下:

    复制代码
    private bool _clicked = false;
    private int _clickx;
    private int _clicky;
    private int _mouseDownCount = 1;
    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (_clicked)
        {
            Point p = new Point();
            p.X = e.X + pictureBox1.Left;
            p.Y = e.Y + pictureBox1.Top;
            pictureBox1.Left = p.X - _clickx;
            pictureBox1.Top = p.Y - _clicky;
            lblMouseMove.Text = string.Format("{0}:{1}", pictureBox1.Left, pictureBox1.Top);
        }
    }
    
    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        _clicked = false;
        lblMouseUp.Text = string.Format("{0}:{1}", e.X,e.Y);
    }
    
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        pictureBox1.Left = e.X;
        pictureBox1.Top = e.Y;
        _clickx = e.X;
        _clicky = e.Y;
        lblMouseDown.Text = string.Format("{0}:{1}:{2}", e.X, e.Y,_mouseDownCount);
        _clicked = true;
        _mouseDownCount += 1;
    }
    复制代码

    五、console的拖放问题
    console 的拖放时最简单的一种操作,因为console本身就支持拖放(如同cmd)。而我们所要做的只是添加一行代码,然后等待用户按下回车。例如:

    string content=Console.ReadLine();
    Console.WriteLine(content);
    Console.ReadLine();
     
     
    分类: C#
    标签: winform拖放
  • 相关阅读:
    超级女声杭州赛区7进5
    究竟怎么了?
    最近发现
    S2SH基于角色权限拦截
    基于S2SH的电子商务网站系统性能优化
    TSQL复习笔记(一)
    用户sa登录失败,该用户与可信sql server连接无关联
    SQL附加数据库报5120的错误的解决办法
    DotNet中配置文件的使用(一)
    JQuery中使用AJAX $.ajax(prop)方法详解
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3189838.html
Copyright © 2011-2022 走看看