.NET:是不是有单击并拖动“类似桌面”的控件?

Posted

技术标签:

【中文标题】.NET:是不是有单击并拖动“类似桌面”的控件?【英文标题】:.NET: is there a Click-and-drag "Desktop-Like" control?.NET:是否有单击并拖动“类似桌面”的控件? 【发布时间】:2010-09-18 19:11:16 【问题描述】:

好的,首先查看Windows桌面的上下文;您可以将桌面上的项目(文件夹、文件)拖到不同的地方,然后它们“停留”在您拖动它们的位置。这似乎是向用户提供的一个非常有用的功能,以便允许他们创建自己的项目“分组”。

我的问题是: .NET 中是否有一个控件可以通过项目集合来近似此行为?

我正在考虑类似于“LargeIcon”模式下的列表视图,但它允许您将图标拖动到控件内的不同位置。

【问题讨论】:

【参考方案1】:

您可以通过执行拖放操作使用标准 ListView 控件来做到这一点。这是一个执行此操作的示例控件:

using System;
using System.Drawing;
using System.Windows.Forms;

public class MyListView : ListView 
  private Point mItemStartPos;
  private Point mMouseStartPos;

  public MyListView() 
    this.AllowDrop = true;
    this.View = View.LargeIcon;
    this.AutoArrange = false;
    this.DoubleBuffered = true;
  

  protected override void OnDragEnter(DragEventArgs e) 
    if (e.Data.GetData(typeof(ListViewItem)) != null) e.Effect = DragDropEffects.Move;
  
  protected override void OnItemDrag(ItemDragEventArgs e) 
    // Start dragging
    ListViewItem item = e.Item as ListViewItem;
    mItemStartPos = item.Position;
    mMouseStartPos = Control.MousePosition;
    this.DoDragDrop(item, DragDropEffects.Move);
  
  protected override void OnDragOver(DragEventArgs e) 
    // Move icon
    ListViewItem item = e.Data.GetData(typeof(ListViewItem)) as ListViewItem;
    if (item != null) 
      Point mousePos = Control.MousePosition;
      item.Position = new Point(mItemStartPos.X + mousePos.X - mMouseStartPos.X,
          mItemStartPos.Y + mousePos.Y - mMouseStartPos.Y);
    
  

【讨论】:

注意,这只适用于 .NET 2.0。此外,您不需要 InteropServices。去掉 OnHandleCreated() 和 CreateParams() 并添加到构造函数 this.AutoArrange = false;和 this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);.【参考方案2】:

我认为最接近的应该是 ListView 控件,但它更像是一个资源管理器窗口。您也许可以创建自己的视图来执行您想要的操作,但您需要在某处手动保存图标位置。

【讨论】:

谢谢;我的意思是写 listview 而不是 listbox...但我不认为 ListView 可以让您在其中拖动项目,是吗? Windows 桌面图标界面实际上是一个用非托管代码(C 或 C++)编写的 Windows ListView 控件。【参考方案3】:

如果您不反对使用 WPF,Josh Smith 已经创建了一个非常简洁的画布,我目前正在将它用于一个项目。它允许您添加控件并将它们拖到画布上。您必须处理画布上加载的内容以及程序下一次加载的位置,但这非常简单。 http://www.codeproject.com/KB/WPF/DraggingElementsInCanvas.aspx

【讨论】:

【参考方案4】:

这取决于这是 Windows 应用程序还是基于 Web 浏览器的应用程序。无论哪种情况,您都需要某种容器来管理控件的位置。您可以使用其 X 和 Y 坐标来管理容器内控件的位置。

您将使用拖动事件来处理实际移动。所以你有拖动开始,同时拖动(你可能会显示一个占位符图形或更改光标),最后是拖动结束(将控件的 x 和 y 设置为新位置)。显然,这些不是实际的事件名称,但搜索“如何处理拖动事件”应该可以帮助您入门。

在 web 环境中,我知道 jquery 具有内置的拖动功能。所以你可能想看看那个。您必须注意的一件大事是在回发之间保持控件的位置。我不确定在这种情况下会发生什么。

【讨论】:

【参考方案5】:

Windows 使用ListView32,这是一个具有拖放占位符功能、自定义边框的内部控件...

图标位置可以存储在 XML 文件中,或应用程序设置中(通过将 XML 作为字符串并在需要时将其转换为文件)。

你可以这样做,例如:

<icons>
    <icon1>
        <name>Icon1</name>
        <text>My PC</text>
        <imageIndex>16</imageIndex>
    </icon1>
    <icon2>
        .....
    </icon2>            
    .....
</icons>

洛伦佐

【讨论】:

以上是关于.NET:是不是有单击并拖动“类似桌面”的控件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用户控件像窗口一样在屏幕上可拖动

VB.Net 如何通过鼠标单击和拖动来旋转矩形

jquery draggable 怎么判断当前控件是不是被禁止拖动

WPF 滑块仅可拖动

WPF实现鼠标拖动控件并带有中间动效

可拖动 iFrame 寄存器单击而不是拖动