分享

C# 拖放操作源码详解二

 wwssdd2000 2014-05-21

在Windows资源管理器中使用拖放操作来移动或复制文件是大家所惯用的方式。Windows资源管理器充分支持拖放操作,而且这也是非常多用户所偏爱的文件使用方式。此外,许多用户非常习惯直接从Windows资源管理器将文件拖放至对应的应用程序中来打开它们。例如,从Windows资源管理器将一个.doc 文档拖放至Microsoft Word即会将该文档在Microsoft Word中打开。

 

图8.15示范如何从Windows资源管理器中拖放文件

 

  图8.15所示是程序范例CH8_DemoForm013.cs的运行画面。显而易见地,您可以从Windows资源管理器将一个或多个文件拖放至窗体上的ListBox控件中,而被拖放的文件的文件名会被添加到ListBox控件中。以下是CH8_DemoForm013.cs的程序代码内容:

 

 





  private void ListBox1_DragEnter(object sender, DragEventArgs e)
  {
   if (e.Data.GetDataPresent(DataFormats.FileDrop))
   {
    e.Effect = DragDropEffects.All;
   }
  }


  private void ListBox1_DragDrop(object sender,DragEventArgs e)
  {
   if(e.Data.GetDataPresent(DataFormats.FileDrop))
   {
    string[] MyFiles;
    int i;


    // 将文件赋给一个数组。
    MyFiles = (string[])(e.Data.GetData(DataFormats.FileDrop));


    // 循环处理数组并将文件添加到列表中。
    for(i = 0;i <= MyFiles.Length - 1;i++)
    {
     ListBox1.Items.Add(MyFiles);
    }
   }
  }

 

图8.16在两个列表间来回拖放一个或多个文件来移动项目

 

  请注意我们在ListBox控件的DragEnter事件处理函数中将Effect属性设定成DragDropEffects.All。由于文件本身实际上并没有被移动或复制,因此拖放源如何设定AllowedEffects将无关紧要,设定All表示对任何的FileDrop都会启用置放。

 

  就本范例而言,DataFormats.FileDrop格式会含有每一个被置放文件的完整路径。本范例的操作逻辑是将所有被拖放文件的完整路径添入 ListBox控件中,当然,您可以采用其他方法,比方说,您可以将被拖放的文件在一个MDI(多文件界面)文件窗口中打开。

 

在两个列表之间来回拖放项目

 

  另外一项常见的拖放需求是,在两个列表(ListView控件)之间来回拖放项目。事实上,我们经常会通过一组按钮来将列表中被选取的项目移至另外一个列表中,不过这样的操作模式需要两次鼠标按键操作(第一次选取项目,第二次单击按钮)。显然,在这样的操作需求中,拖放操作会较受青睐,因为它只需单一动作即可完成(选取并拖曳)。

 

  图8.16所示是程序范例CH8_DemoForm014.cs的运行画面。显而易见地,您可以在两个列表间来回拖放一个或多个文件来移动项目。本程序范例的设计重点说明如下:

 


  • 由于两个列表的ListView控件都可以作为置放目标,因此务必将这两个ListView控件的AllowDrop属性设定成True。
  • 请将两个ListView控件的MultiSelect属性设定成True。
  • 请将两个ListView控件的FullRowSelect属性设定成True。
  • 以下是程序范例CH8_DemoForm014.cs的程序代码内容。于Load事件处理函数中所调用的 PopulateListView() 程序主要是用来初始化两个ListView控件:

 

 





  private void CH4_DemoForm067_Load(object sender, EventArgs e)
  {
   this.PopulateListView();
  }
  private void ListView_ItemDrag(object sender,
   System.Windows.Forms.ItemDragEventArgs e)
  {
   ListViewItem[] myItems = 
    new ListViewItem[((ListView)(sender)).SelectedItems.Count];
   int i = 0;
   // 循环处理拖放来源的 SelectedItems 集合。
   foreach(ListViewItem myItem in 
    ((ListView)(sender)).SelectedItems)
   {
    // 将ListViewItem新增至ListViewItems的数组中。
    myItems = myItem;
    i = i + 1;
   }
   // 建立一个DataObject对象来包含ListViewItem的数组。
   ((ListView)(sender)).DoDragDrop(new
    DataObject("System.Windows.Forms.ListViewItem()", 
    myItems), DragDropEffects.Move);
  }


  private void ListView_DragEnter(object sender,
   System.Windows.Forms.DragEventArgs e)
  {
   // 检查自定义的 DataFormat ListViewItem 数组。
   if (e.Data.GetDataPresent(
    "System.Windows.Forms.ListViewItem()"))
   {
    e.Effect = DragDropEffects.Move;
   }
   else
   {
    e.Effect = DragDropEffects.None;
   }
  }
  private void ListView_DragDrop(object sender,
   System.Windows.Forms.DragEventArgs e)
  {
   ListViewItem[] myItems =
    (ListViewItem[])(
    e.Data.GetData("System.Windows.Forms.ListViewItem()"));
   int i = 0;
   foreach (ListViewItem myItem in myItems)
   {
    // 将项目添加到目标列表中。
    ListViewItem item = new ListViewItem(myItems.Text);
    item.SubItems.Add(myItems.SubItems[1].Text);
    ((ListView)(sender)).Items.Add(item);


    // 从源列表移除项目。
    if (sender == ListView1)
    {
     istView2.Items.Remove(ListView2.SelectedItems[0]);
    }
    else
    {
     ListView1.Items.Remove(ListView1.SelectedItems[0]);
    }
    i = i + 1;
   }
  }

  您或许会觉得奇怪,为什么不使用ListBox控件而要使用ListView控件。最主要的理由是,ListBox控件并不支持拖曳多个项目,单击列表会使得多重选取失效。

 

  ListView与TreeView控件都拥有一个ItemDrag事件来促进拖曳操作。在本范例中,我们使用单一个ItemDrag事件处理函数来处理两个ListView控件的ItemDrag事件。其中的sender参数代表初始化拖曳的控件。

 

  由于DataFormats类的成员并不包括ListViewItem类型,所以数据必须当作一个系统Type来传递。ItemDrag事件处理函数的程序代码会创建一个类型为ListViewItem的数组并循环处理SelectedItems集合以便添入数组。在DoDragDrop方法中,一个新的DataObject对象会被创建并以数组来添入。您可以使用相同的技巧来拖放任何的系统Type。

 

  在DragDrop事件处理函数中,我们会将DataObject对象中的数组复制到一个新的ListViewItem数组中,而且每一个ListViewItem会被添加到目标ListView控件的Items集合中。

 

在两个TreeView之间来回拖放节点

 

程序范例

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多