gpt4 book ai didi

c# - 分隔线拖放树节点 c# WinForms

转载 作者:行者123 更新时间:2023-12-05 03:08:12 34 4
gpt4 key购买 nike

我正在尝试复制以下拖放功能:DefaultDragDropWindows

但是,我无法绘制那条黑线。不知何故,我最终每个节点有三行。我计算包含树节点的矩形的上部、中部和下部,并根据此绘制其中一条线。如果我确实使用 treeView.Invalidate() 屏幕闪烁太多并且看不到该行。我也尝试过使用 graphics.clear(treeView.BackColor) 但它也会清除我的树节点。

演示: DragDrop ASE

代码 - 树事件:

public void ItemDrag(object sender, ItemDragEventArgs e)
{
TreeNode selectedNode = (TreeNode)e.Item;
if (e.Button == MouseButtons.Left && !selectedNode.Name.Contains("=") && !selectedNode.Name.Contains("#"))
_treeView.DoDragDrop(selectedNode, DragDropEffects.Move);

}

public void DragEnter(object sender, DragEventArgs e)
{
e.Effect = e.AllowedEffect;
}

public void DragOver(object sender, DragEventArgs e)
{
try
{
if (!mousePoint.Equals(Cursor.Position))
{
mousePoint = Cursor.Position;
bool droppable;
TreeNode destinationNode = null;
Point pointInTree = _treeView.PointToClient(new Point(e.X, e.Y));
if (e.Data.GetDataPresent(typeof(TreeNode)))
{
destinationNode = _treeView.GetNodeAt(pointInTree);
TreeNode souceNode = (TreeNode) e.Data.GetData(typeof(TreeNode));
droppable = true;
}

else droppable = false;

e.Effect = droppable ? DragDropEffects.Move : DragDropEffects.None;

Point pt = _treeView.PointToClient(new Point(e.X, e.Y));
_treeView.SelectedNode = _treeView.GetNodeAt(pt);

int dropLocation = CalculateNodeHooverArea(destinationNode, pointInTree);
if(_dropLocation!=dropLocation)
{
switch (dropLocation)
{
case 0:
DrawLine(NodePosition.Above);
break;
case 2:
DrawLine(NodePosition.Below);
break;
case 1:
DrawLine(NodePosition.In);
break;
}
_dropLocation = dropLocation;
}

}
}
catch (Exception exception)
{
Debug.WriteLine("TreeViewDragOverEvent: " + exception.Message);
}
}
public void DragDrop(object sender, DragEventArgs e)
{
try
{
Point targetPoint = _treeView.PointToClient(new Point(e.X, e.Y));
TreeNode targetNode = _treeView.GetNodeAt(targetPoint);
TreeNode draggedNode = (TreeNode)e.Data.GetData(typeof(TreeNode));
if (!draggedNode.Equals(targetNode) && !draggedNode.Nodes.Find(targetNode.Name, true).Any() &&
targetNode.Parent != null && !targetNode.Name.Contains("=") && !targetNode.Name.Contains("#"))
{
int nodeLocation = CalculateNodeHooverArea(targetNode, targetPoint);

if (e.Effect == DragDropEffects.Move)
draggedNode.Remove();

switch (nodeLocation)
{
case 0:
if (targetNode.Parent != null)
targetNode.Parent.Nodes.Insert(targetNode.Index, draggedNode);
break;
case 1:
targetNode.Nodes.Add(draggedNode);
break;
case 2:
if (targetNode.Parent != null)
targetNode.Parent.Nodes.Insert(targetNode.Index + 1, draggedNode);
break;
}
}
//SaveMemento();
_treeView.Invalidate();
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
}
}

处理线条绘制的方法:

    private void DrawLine(NodePosition position)
{
Graphics g = _treeView.CreateGraphics();
Pen customPen = new Pen(Color.DimGray, 1) { DashStyle = DashStyle.Dash };
if (position == NodePosition.Above)
g.DrawLine(customPen, new Point(0, _treeView.SelectedNode.Bounds.Top),
new Point(_treeView.Width - 4, _treeView.SelectedNode.Bounds.Top));

else if (position == NodePosition.Below)
g.DrawLine(customPen, new Point(0, _treeView.SelectedNode.Bounds.Bottom),
new Point(_treeView.Width - 4, _treeView.SelectedNode.Bounds.Bottom));

else
{
g.DrawLine(customPen, new Point(_treeView.SelectedNode.Bounds.X + _treeView.SelectedNode.Bounds.Width,
_treeView.SelectedNode.Bounds.Y +_treeView.SelectedNode.Bounds.Height / 2),
new Point(_treeView.Width - 4, _treeView.SelectedNode.Bounds.Y + _treeView.SelectedNode.Bounds.Height / 2));
}

customPen.Dispose();
g.Dispose();
}

这个问题能以某种方式解决吗?还是我应该研究一种显示此类信息的不同方式? (例如工具提示)?

最佳答案

您真的不必每次到达新的 TreeNode 附近时都画线。在我看来,每次在拖放事件中继续使用 Graphics 对象来绘制和删除某些内容并不是一个干净的解决方案。相反,这是我称之为实现相同目标的更“更清洁”的方式-

  • 在您的 Windows 窗体上,绘制一条线作为静态控件并将其可见性最初设置为 false。现在你如何画一条线? 添加一个标签控件,添加一个实体或 3D 边框,清除文本,并设置一个固定的高度 - 可以是 2 像素,宽度根据需要。将此标签放在表单左下角的某个位置,它不会出现在 UI 上的其他控件中。

  • 代替 DrawLine 方法,将其称为 ShowLine 或其他名称。在这个方法中,根据 TreeView 节点的位置,动态地将这个新标签(实际上是一条线)的 X 和 Y 位置设置到新位置,并使其可见。因此,每次在 DragOver 上它都会在不同的 X 和 Y 位置上可见,并为您提供所需的相同体验。

  • 一旦将项目放入节点内(即拖放操作完成),将此线标签的可见性设置为 false,并将其 X 和 Y 位置设置回原始位置(在本例中为左下角)。

关于c# - 分隔线拖放树节点 c# WinForms,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45838579/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com