和WinForm类似,在WPF中,也有拖放功能。所谓拖放,是指将目标从拖动源中拖出,然后放置到目标对象上。因此,在WPF的拖放过程中,有5个需要注意的:

  • 目标:需要拖放的对象,这个对象可能是一副图片,或者是TextBox中的文字,也可能是List中的某一项。
  • 拖动源:目标原来所在的容器,例如一个Canvas,一个TextBox,或者一个List。
  • 目标对象:目标的“新家”,例如一个Canvas,一个TextBox,或者一个List。
  • 拖动(Drag):一个动作,一般是在目标上按住鼠标左键,然后移动鼠标。
  • 放置(Drop):在目标对象上松开鼠标左键。 

    目标

    在WPF中,我们使用一个实现了IDataObject的接口来封装目标:这个接口有以下几个代表方法:

  • GetData :检索指定数据格式的数据对象。
  • GetDataPresent :查看是否具有指定格式的数据,或者数据是否可以转换为指定格式。
  • GetFormats :返回一个格式列表,此数据对象中的数据以这些格式存储,或可以转换为这些格式。
  • SetData :在此数据对象中存储指定的数据。

WPF 提供 DataObject 类中的 IDataObject 的基本实现;对于许多常见数据传输方案,常用 DataObject 类已足够满足要求。

以下代码我们用DataObject包装了ListView中的一行数据:

DataObject data = new DataObject(typeof(ItemInfo), listview.SelectedItem);

目标对象

UIElement类中,有一个AllowDrop属性,用来指此元素是否可用作拖放操作的目标。在默认情况下该属性的值为false。因此,需要将该值设置为True:

<object AllowDrop=”bool” …/> 

拖动

前面提到了,拖动有是由两个动作所构成:按下鼠标左键,移动鼠标:

代码:

protected bool m_IsDraging = false;
protected Point m_DragStartPoint;

private void LV_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
   m_DragStartPoint = e.GetPosition(null);
}

private void LV_PreviewMouseMove(object sender, MouseEventArgs e)
{
    var lv = sender as ListView;

    if (lv.SelectedItem == null) return;

    if (e.LeftButton == MouseButtonState.Pressed && !m_IsDraging)
    {
       Point position = e.GetPosition(null);

    if (e.LeftButton == MouseButtonState.Pressed && !m_IsDraging)
    {
       Point position = e.GetPosition(null);

       if (Math.Abs(position.X - m_DragStartPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
          Math.Abs(position.Y - m_DragStartPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
       {
          m_IsDraging = true;
          DataObject data = new DataObject(typeof(ItemInfo), lv.SelectedItem);
          DragDropEffects de = DragDrop.DoDragDrop(lv, data, DragDropEffects.Copy);
          m_IsDraging = false;
       }
    }
}

以上代码里,我们使用代码:

代码:

DataObject data = new DataObject(typeof(ItemInfo), lv.SelectedItem);
DragDropEffects de = DragDrop.DoDragDrop(lv, data, DragDropEffects.Copy);

来发起一个拖动动作。

放置

WPF提供了一系列和放置有关的事件:

  • DragEnter :将对象拖至放置目标的边框内时发生此事件。
  • DragLeave :将对象拖出放置目标的边框时发生此事件。
  • DragOver :在放置目标的边框内拖动(移动)对象时发生此事件。
  • Drop :将对象放到放置目标上时发生此事件。

 

代码:

private void FileSystemListView_PreviewDrop(object sender, DragEventArgs e)
{
    var data = e.Data;
    if (data.GetDataPresent(typeof(FileSystemListView.ItemInfo)))
    {
       var info=data.GetData(typeof(FileSystemListView.ItemInfo)) as FileSystemListView.ItemInfo;
      MessageBox.Show(info.Name);
    }
}

这里的e.Data就是对目标的封装。

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐