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 + "\r\n";
        }
    }
                
}
復制代碼

二、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拖放


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM