【发布时间】:2011-09-14 12:29:51
【问题描述】:
我有一个简单的 TreeView,其 HotTracking 属性设置为 True。当我将鼠标移到一个项目上时它可以工作。但是当我使用 Drag&Drop 并将某些东西拖到 TreeView 项目上时它不起作用。有没有办法将 HotTracking 与 DragDrop 一起使用?或者有什么解决方法?
【问题讨论】:
标签: .net vb.net drag-and-drop treeview
我有一个简单的 TreeView,其 HotTracking 属性设置为 True。当我将鼠标移到一个项目上时它可以工作。但是当我使用 Drag&Drop 并将某些东西拖到 TreeView 项目上时它不起作用。有没有办法将 HotTracking 与 DragDrop 一起使用?或者有什么解决方法?
【问题讨论】:
标签: .net vb.net drag-and-drop treeview
按照设计,控件仅获取 D+D 通知,没有鼠标消息。您可以简单地自己选择节点:
private void treeView1_DragOver(object sender, DragEventArgs e) {
if (e.Data.GetDataPresent("something")) {
var pos = treeView1.PointToClient(new Point(e.X, e.Y));
var hit = treeView1.HitTest(pos);
if (hit.Location == TreeViewHitTestLocations.Label) {
treeView1.SelectedNode = hit.Node;
e.Effect = DragDropEffects.Copy;
}
else e.Effect = DragDropEffects.None;
}
}
您通常需要做更多的工作才能让用户滚动视图并展开节点。
【讨论】:
按照@Hans 的建议选择节点是一个简单的解决方案,但如果节点选择有一些事件,或者您只需要保留所选节点,则可能无法使用。 我发现的唯一方法是使用 VisualStylesRenderer custumDraw 节点。
private void plTree_DragOver(object sender, DragEventArgs e)
{
Point pt = plTree.PointToClient(new Point(e.X, e.Y));
var overNode = plTree.GetNodeAt(pt);
bool canMoveTo = overNode != null &&
TreeNodeIsFolder(overNode) &&
!IsFirstNodeParentToSecond(GetDraggedNodes(e)[0], overNode);// all dragged nodes are of the same parent
e.Effect = canMoveTo ? DragDropEffects.Move : DragDropEffects.None;
if (overNode == null) return;
if (_lastCustomDrawNode != overNode)
{
NormalDrawNode(_lastCustomDrawNode);
CustomDrawNode(overNode);
}
_lastCustomDrawNode = overNode;
}
private void NormalDrawNode(TreeNode aNode)
{
if (aNode == null) return;
if (_normalNodeRenderer == null)
_normalNodeRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 1);
Debug.WriteLine("normal render" + DateTime.Now);
RenderTreeNode(_normalNodeRenderer, aNode, true);
_lastCustomDrawNode = null;
}
private void CustomDrawNode(TreeNode aNode)
{
if (_hotNodeRenderer == null)
_hotNodeRenderer = new VisualStyleRenderer("Explorer::TreeView", 1, 2);
Debug.WriteLine("custom render" + DateTime.Now);
RenderTreeNode(_hotNodeRenderer, aNode, false);
}
private void RenderTreeNode(VisualStyleRenderer renderer, TreeNode aNode, bool drawDefaultBck)
{
if(_treeGraphics == null)
_treeGraphics = plTree.CreateGraphics();
const int iconShift = 21;
Rectangle aRec = aNode.Bounds;
var bckRec = new Rectangle(aRec.Location.X - iconShift, aRec.Location.Y, aRec.Width + iconShift, aRec.Height);
if (!drawDefaultBck)
renderer.DrawBackground(_treeGraphics, bckRec);
else
_treeGraphics.FillRectangle(_treebckgBrush, bckRec);
var textRec = new Rectangle(aRec.Location.X + 1, aRec.Location.Y - 1, aRec.Width, aRec.Height);
TextRenderer.DrawText(_treeGraphics, aNode.Text, GetTreeNodeFont(aNode), textRec, Color.FromKnownColor(KnownColor.ControlText));
var imgRec = new Rectangle(aRec.Location.X + 2 - iconShift, aRec.Location.Y, 16, 16);
renderer.DrawImage(_treeGraphics, imgRec, ImageListTree.Images[aNode.ImageIndex]);
}
这篇文章对主题绘图有很大帮助: VisualStyleRenderer and themes (WinForms)
【讨论】: