在列表视图中的项目之间绘制胡萝卜

时间:2012-11-20 16:34:12

标签: wpf drag-and-drop treeview

我正在尝试在WPF TreeView中实现对项目的拖放重新排序,并希望能够在树视图中的项目之间向用户显示carret,以便能够指示当放置操作完成时,项目将被定位,有点像下面的屏幕截图(树视图不是列表视图除外)

screenshot of the desired effect

我想我理解拖放是如何在WPF中工作的,并且计划通过处理OnDragOver事件来确定所需的位置来实现这一点,但是我不知道如何绘制由此产生的carret效果。

我是否应该在列表视图中在我想要放置项目的位置插入一个虚拟项目(请注意,理想情况下我不希望列表中的项目明显移动,因此不知何故此项目占用的高度会有是0),还是有更简单的方法来达到同样的效果?

2 个答案:

答案 0 :(得分:1)

我使用了一个装饰器在第三方数据网格中绘制掉落指南。我记得很多细节都是为了获得可接受的用户体验。如拖动时滚动,延迟滚动。同样将指南绘制到行的可见宽度并非易事。最后但同样重要的是,装饰者有自己的特点。

答案 1 :(得分:1)

  1. 您需要抽象Adorner类的子类。
  2. 我已经覆盖了OnRender以绘制指南/插入符号(一些几何图形的线条没什么特别的)
  3. 我在Adorner上有一个公共属性,用于绘制装饰者的DataGrid
  4. 具有两个参数的公共方法SetMousePosition:鼠标悬停在其上的MouseCoords + DataGridRow。我使用这些数据来确定在DataRow上方或下方绘制指南/插入符的位置,但是您在DataGrid的可视区域中绘制。我做了一些额外的计算,以确定是否需要在等等之前或之后插入该项目。
  5. 如果您有自定义装饰器,现在可以将其添加到DataGrid的装饰器层中:

            var adornerLayer = AdornerLayer.GetAdornerLayer(_dataGrid);
            adornerLayer.Add(_dragGuide);
    

    但是,无论出于何种原因拖动操作结束,您都需要将其删除,否则指南/插入符号仍然可见:

    var adornerLayer = AdornerLayer.GetAdornerLayer(_dataGrid);
    adornerLayer.Remove(_dragGuide);
    

    如果你有这个,那么你可以开始处理所有特殊情况: 在该区域中删除所有列的行 将行放在行所在区域下方。 丢弃不完全可见的行(底部或上部滚动不在视线范围内) 从窗口的不同实例拖放。 等等。

    最后,大多数用户都不喜欢努力工作,因为他们没有线索可以拖放,或者他们更喜欢使用按钮。

    但我希望上面给你一个kickstart。

    啊,我忘记了这个对我有帮助的链接:MSDN doc: Adorners overview