我已经实现了System.Windows.Forms表单中用于拖放的“基本”功能。 (请参见下面的代码)
但是现在我遇到了一个问题:想象一个文件夹结构,并且Folders / TreeNodeCollections包含项目/ TreeNodes。现在,当我想将一个项目从列表中的一个文件夹移动到另一个文件夹时,当一个项目是列表中的最后一个可见内容时,它不会在列表中滚动。
仅当我在列表中滚动并且该文件夹是最后一个可见的东西时才有效,但也只能向下滚动(向上滚动不适用于任何一种方式)。问题很奇怪!
代码:
public override void ConditionDown()
{
if (treeControl1.SelectedNode != null)
{
var cmd = (Commands.DataCommand<string>)mApplicationData.CommandFactory.Create(string.Concat(CommandPrefix, "ConditionDown"));
cmd.Data = treeControl1.SelectedNode.Text;
cmd.Execute();
}
UpdateData();
}
public override void ConditionUp()
{
if (treeControl1.SelectedNode != null)
{
if (MultipleObjectTypesSupported)
{
Commands.ObjectGroupConditionUp cmd = (Commands.ObjectGroupConditionUp)mApplicationData.CommandFactory.Create("ObjectGroupConditionUp");
cmd.Data = treeControl1.SelectedNode.Text;
cmd.Execute();
}
else
{
Commands.DisplayGroupConditionUp cmd = (Commands.DisplayGroupConditionUp)mApplicationData.CommandFactory.Create("DisplayGroupConditionUp");
cmd.Data = treeControl1.SelectedNode.Text;
cmd.Execute();
}
}
UpdateData();
}
private void treeControl1_NodeDragDrop(object sender, DragEventArgs e)
{
var pointInTree = treeControl1.PointToClient(new Point(e.X, e.Y));
TreeNode n = treeControl1.GetNodeAt(pointInTree);
if (n.IsUngroupedNode() == true || n.Parent?.IsUngroupedNode() == true)
{
mNodesToDrop = null;
}
else
{
if (mNodesToDrop != null && mNodesToDrop.Any())
{
if (mNodePosition == NodePosition.Middle)
{
foreach (TreeNode node in mNodesToDrop)
{
if (node.Tag is ObjectGroup)
{
Commands.IGroupSubGroupCommand cmd = null;
if (e.Effect == DragDropEffects.Move)
{
cmd = (Commands.IGroupSubGroupCommand)mApplicationData.CommandFactory.Create(CommandPrefix + "SubGroupMove");
}
else if (e.Effect == DragDropEffects.Copy)
{
cmd = (Commands.IGroupSubGroupCommand)mApplicationData.CommandFactory.Create(CommandPrefix + "SubGroupAdd");
}
if (cmd != null)
{
cmd.Data = node.Text;
cmd.ParentGroupName = n.Text;
cmd.Execute();
}
}
else if (node.Tag is ObjectType)
{
Commands.IGroupTypeCommand cmd = null;
if (e.Effect == DragDropEffects.Move)
{
cmd = (Commands.IGroupTypeCommand)mApplicationData.CommandFactory.Create(CommandPrefix + "TypeMove");
}
else if (e.Effect == DragDropEffects.Copy)
{
cmd = (Commands.IGroupTypeCommand)mApplicationData.CommandFactory.Create(CommandPrefix + "TypeAdd");
}
if (cmd != null)
{
cmd.Data = n.Text;
cmd.ObjectClass = ((ObjectType)node.Tag).Class;
cmd.ObjectTypeName = ((ObjectType)node.Tag).Name;
cmd.Execute();
}
}
}
}
else
{
var group = from x in mNodesToDrop
where x.Tag is ObjectGroup
let p = x.Parent?.Text ?? "empty"
group x by p into g
select new { Parent = g.Key, Nodes = g.ToList() };
if (n.Tag is ObjectGroup)
{
var groupToAdd = GetRootObjectGroupCollection();
if (n.Parent != null)
groupToAdd = ((ObjectGroup)n.Parent.Tag).SubObjectGroups;
foreach (var g in group)
{
var nodesToTemove = g.Nodes.ToList().OrderByDescending(x => x.Index);
var groupToRemove = GetRootObjectGroupCollection();
if (nodesToTemove.FirstOrDefault().Parent != null)
groupToRemove = ((ObjectGroup)nodesToTemove.FirstOrDefault().Parent.Tag).SubObjectGroups;
foreach (var node in g.Nodes)
{
bool useAdd = false;
var indexToChange = node.Index;
int newIndex = -1;
if (mNodePosition == NodePosition.Above)
{
newIndex = n.Index;
}
else if (mNodePosition == NodePosition.Below)
{
newIndex = n.Index + 1;
if (newIndex > groupToAdd.Count - 1)
useAdd = true;
}
if (groupToAdd == groupToRemove)
{
if (indexToChange < newIndex)
newIndex = newIndex - 1;
}
groupToRemove.RemoveAt(indexToChange);
if (useAdd)
groupToAdd.Add(node.Tag as ObjectGroup);
else
groupToAdd.Insert(newIndex, node.Tag as ObjectGroup);
}
}
}
}
}
mNodesToDrop = null;
mGraphics.Dispose();
UpdateData();
Refresh();
}
}
private void treeControl1_NodeDrag(object sender, ItemDragEventArgs e)
{
TreeNode node = (TreeNode)e.Item;
if (node.IsUngroupedNode())
{
mNodesToDrop = null;
return;
}
mNodesToDrop = new List<TreeNode>();
foreach (var n in treeControl1.SelectedNodes)
mNodesToDrop.Add(n);
DoDragDrop(e.Item, GetDragDropEffect());
}
private void treeControl1_NodeDragOver(object sender, DragEventArgs e)
{
if (MultipleObjectTypesSupported)
{
mNodePosition = NodePosition.Middle;
e.Effect = GetDragDropEffect();
}
else
{
NodePosition currentNodePosition = mNodePosition;
var pointInTree = treeControl1.PointToClient(new Point(e.X, e.Y));
TreeNode n = treeControl1.GetNodeAt(pointInTree);
if (n.IsUngroupedNode() || n?.Tag is ObjectType)
e.Effect = DragDropEffects.None; // No drag over "ungrouped" node
else if (n?.Parent?.IsUngroupedNode() == true)
e.Effect = DragDropEffects.None;
else
e.Effect = GetDragDropEffect();
if (n?.Tag is ObjectGroup)
{
var positionYAbove = pointInTree.Y - n.Bounds.Top;
var positionYBelow = pointInTree.Y - n.Bounds.Bottom;
var height = n.Bounds.Height * 0.15;
if (positionYAbove > 0 && positionYAbove <= height)
{
currentNodePosition = NodePosition.Above;
}
else if (positionYBelow < 0 && System.Math.Abs(positionYBelow) <= height)
{
currentNodePosition = NodePosition.Below;
}
else
{
currentNodePosition = NodePosition.Middle;
}
if (mNodePosition != currentNodePosition)
{
mNodePosition = currentNodePosition;
if (mNodePosition != NodePosition.Middle)
{
if (mNodePosition == NodePosition.Above)
ShowLine(n.Bounds.Top, treeControl1.Width - 4);
else if (mNodePosition == NodePosition.Below)
ShowLine(n.Bounds.Bottom, treeControl1.Width - 4);
}
else
{
treeControl1.SelectedNode = n;
}
}
}
}
private void treeControl1_NodeDragEnter(object sender, DragEventArgs e)
{
mGraphics = treeControl1.CreateGraphics();
e.Effect = DragDropEffects.Move;
}
private void treeControl1_MouseUp(object sender, MouseEventArgs e)
{
var pointInTree = new Point(e.X, e.Y);
TreeNode n = treeControl1.GetNodeAt(pointInTree);
if (n != null)
{
if (mSelectedNodeChanged == false && !n.IsUngroupedNode() && !n.IsTypeNode())
{
treeControl1.LabelEdit = true;
treeControl1.AfterLabelEdit += OnEditRename;
treeControl1.BeforeLabelEdit += BeforeEdit;
}
}
}
private void treeControl1_MouseDown(object sender, MouseEventArgs e)
{
}
}