C# 在使用拖放时,我是否可以使树状视图扩展用户悬停的节点? 简言之:
在进行拖放操作时,悬停在.Net 2.0中是否有任何内置函数可以扩展C# 在使用拖放时,我是否可以使树状视图扩展用户悬停的节点? 简言之:,c#,winforms,treeview,hover,drag-and-drop,C#,Winforms,Treeview,Hover,Drag And Drop,在进行拖放操作时,悬停在.Net 2.0中是否有任何内置函数可以扩展TreeNodes 我在VisualStudio2005中使用C# 更详细地说: 我已经用一个多级多节点树(想想组织结构图或文件/文件夹对话框)填充了一个Treeview控件,我想使用拖放来移动树中的节点 拖放代码运行良好,我可以拖放到任何可见节点上,但是我希望我的控件在文件夹窗格上拖动文件时的行为与Windows资源管理器相同。具体地说,如果将鼠标悬停1/2秒左右,我希望每个文件夹都能打开 我已经开始使用线程和睡眠方法开发一个
TreeNode
s
我在VisualStudio2005中使用C#
更详细地说:
我已经用一个多级多节点树(想想组织结构图或文件/文件夹对话框)填充了一个Treeview
控件,我想使用拖放来移动树中的节点
拖放代码运行良好,我可以拖放到任何可见节点上,但是我希望我的控件在文件夹窗格上拖动文件时的行为与Windows资源管理器相同。具体地说,如果将鼠标悬停1/2秒左右,我希望每个文件夹都能打开
我已经开始使用线程
和睡眠
方法开发一个解决方案,但我遇到了一些问题,想知道是否已经有了解决方案,如果没有,我将全力以赴学习如何使用线程(是时候了,但我希望这个应用程序能尽快推出)
我是否需要编写自己的代码来处理在拖放模式下悬停时展开TreeNode
编辑
我有一个新的解决方案,有点牵强,但它是有效的。。。它使用DelayedAction
类来处理主线程上操作的延迟执行:
DelayedAction
public class DelayedAction<T>
{
private SynchronizationContext _syncContext;
private Action<T> _action;
private int _delay;
private Thread _thread;
public DelayedAction(Action<T> action)
: this(action, 0)
{
}
public DelayedAction(Action<T> action, int delay)
{
_action = action;
_delay = delay;
_syncContext = SynchronizationContext.Current;
}
public void RunAfterDelay()
{
RunAfterDelay(_delay, default(T));
}
public void RunAfterDelay(T param)
{
RunAfterDelay(_delay, param);
}
public void RunAfterDelay(int delay)
{
RunAfterDelay(delay, default(T));
}
public void RunAfterDelay(int delay, T param)
{
Cancel();
InitThread(delay, param);
_thread.Start();
}
public void Cancel()
{
if (_thread != null && _thread.IsAlive)
{
_thread.Abort();
}
_thread = null;
}
private void InitThread(int delay, T param)
{
ThreadStart ts =
() =>
{
Thread.Sleep(delay);
_syncContext.Send(
(state) =>
{
_action((T)state);
},
param);
};
_thread = new Thread(ts);
}
}
public class AutoExpandTreeView : TreeView
{
DelayedAction<TreeNode> _expandNode;
public AutoExpandTreeView()
{
_expandNode = new DelayedAction<TreeNode>((node) => node.Expand(), 500);
}
private TreeNode _prevNode;
protected override void OnDragOver(DragEventArgs e)
{
Point clientPos = PointToClient(new Point(e.X, e.Y));
TreeViewHitTestInfo hti = HitTest(clientPos);
if (hti.Node != null && hti.Node != _prevNode)
{
_prevNode = hti.Node;
_expandNode.RunAfterDelay(hti.Node);
}
base.OnDragOver(e);
}
}
您可以使用DragOver事件;拖动对象时,它会重复激发 延迟后打开可以很容易地通过两个额外的变量来完成,这两个变量记录鼠标下的最后一个对象和时间。不需要线程或其他技巧(在我的示例中为lastDragDestination和lastDragDestinationTime) 根据我自己的代码:
TreeNode lastDragDestination = null;
DateTime lastDragDestinationTime;
private void tvManager_DragOver(object sender, DragEventArgs e)
{
IconObject dragDropObject = null;
TreeNode dragDropNode = null;
//always disallow by default
e.Effect = DragDropEffects.None;
//make sure we have data to transfer
if (e.Data.GetDataPresent(typeof(TreeNode)))
{
dragDropNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
dragDropObject = (IconObject)dragDropNode.Tag;
}
else if (e.Data.GetDataPresent(typeof(ListViewItem)))
{
ListViewItem temp (ListViewItem)e.Data.GetData(typeof(ListViewItem));
dragDropObject = (IconObject)temp.Tag;
}
if (dragDropObject != null)
{
TreeNode destinationNode = null;
//get current location
Point pt = new Point(e.X, e.Y);
pt = tvManager.PointToClient(pt);
destinationNode = tvManager.GetNodeAt(pt);
if (destinationNode == null)
{
return;
}
//if we are on a new object, reset our timer
//otherwise check to see if enough time has passed and expand the destination node
if (destinationNode != lastDragDestination)
{
lastDragDestination = destinationNode;
lastDragDestinationTime = DateTime.Now;
}
else
{
TimeSpan hoverTime = DateTime.Now.Subtract(lastDragDestinationTime);
if (hoverTime.TotalSeconds > 2)
{
destinationNode.Expand();
}
}
}
}
不起作用。。。我试过这个。在拖放模式下,不会触发OnNodeMouseHover。+1表示使用Dragver的解决方案。很好的“我还在同一个节点上吗?”逻辑也很好。很好,非常感谢。我没有意识到你可以在bady方法之外像那样实例化,所以我学到了更多:-)还有一个问题,你提到的IconObject是什么?我从您的代码中导出了一个解决方案,但没有使用它。另外,我忽略了listview代码,因为它与我的情况无关。IconObject ListView是否相关?这来自一个允许管理和关联不同对象的项目;它包含业务、人员、计算机、软件等。业务包含部门,部门包含人员、计算机、计算机包含软件等。某些对象分配给其他对象(显示在树视图中),而其他对象未分配并保留在常规池(如未分配的计算机池)中,显示在列表视图中。所有对象都继承自IconObject,它是我定义公共属性和逻辑的基类。(子类定义了一个列表/树图像、一些额外的属性和其他一些)