防止在当前控件(TreeView中的TreeNodes)之外进行拖放操作。

4
我是一名有用的助手,我可以为您翻译文本。
我正在维护一个Windows应用程序,该程序在一个窗口中拥有多个窗体(form1form2form3)。目前我把其他的 form2form3 视为黑匣子。在 form1 中,我有一个 TreeView,并且我正在实现该 TreeView 的拖放功能。
我该如何防止在 form1 控件之外进行拖放操作?
我正在实现三个事件处理程序:
private void treeView_ItemDrag (...)
{
    DoDragDrop(e.Item, DragDropEffects.Move);
} 

private void treeView_DragEvent (...) 
{
    e.Effect = DragDropEffects.Move;
}

private void treeView_DragDrop (...)
{
    //the node move logic here
}
form2form3之间存在拖放关系,因此当我从form1中的一个节点拖到form3时,默认允许移动(坏事)。我希望能够通过form1控件代码来防止这种情况发生。

如何防止在form1控件之外进行拖放?我已经查看了_DragLeave事件,但是我不确定如何在没有DragEventArgs的情况下控制操作。

3个回答

6

在Cursor对象中有一个不太常见的属性,可以将鼠标移动限制在某个矩形区域内。

可以将其作为Form1的全局变量。

   Rectangle _originalClip;

这段代码应放在Form1_Load事件中。
  _originalClip = Cursor.Clip;

这可能是在您的TreeView.ItemDrag事件中,将光标强制限制在Form1客户区内。
   Cursor.Clip = form1.RectangleToScreen(form1.ClientRectangle);

现在你需要恢复原始的剪辑区域。一个好的位置将是在treeView.DragDrop中。但为了保险起见,也要把它放在Form1_Closing事件中。

   Cursor.Clip = _originalClip;

谢谢Steve,那看起来像是一个简单的解决方案,我会尝试一下。 - MattyG

2
您可以检查鼠标拖动操作是否超出允许区域,如果是,则取消拖动操作。
MSDN中有一个很好的示例,使用QueryContinueDrag事件来实现此目的。我认为您可以在解决方案的基础上使用它。
链接:DragAction枚举

1

我知道这是一个老话题,但由于我从未找到如何防止控件拖出面板的好方法,所以我想提供我自己整理的解决方案。我使用了上面的一些提示和自己的一些工作。

private void Form1_Load(object sender, EventArgs e)
        {
            _originalClip = Cursor.Clip;
        }

        private void pb_MouseMove(object sender, MouseEventArgs e)
        {
            PictureBox pb = (PictureBox)sender;
            if (e.Button == MouseButtons.Left)
            {
                Size sz = new Size(panel1.RectangleToScreen(panel1.ClientRectangle).Width - (pb.Width), panel1.RectangleToScreen(panel1.ClientRectangle).Height - (pb.Height));
                Point loc = new Point(panel1.RectangleToScreen(panel1.ClientRectangle).X + (pb.Width / 2), panel1.RectangleToScreen(panel1.ClientRectangle).Y + (pb.Height / 2));
                Rectangle rct = new Rectangle(loc, sz);
                Cursor.Clip = rct;
                pb.Left += (e.X - x);
                pb.Top += (e.Y - y);
            }
        }
        private void pb_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor.Clip = _originalClip;
        }

这段代码使用Cursor.Clip方法和一个大小设置为包含一系列Pictureboxes(代码中为“pb”)的面板(代码中为“panel1”)的矩形对象。新矩形的大小设置为父面板减去Picturebox的宽度和高度,位置设置为panel1的位置减去Picturebox宽度和高度的一半。这将提供一个矩形,限制Picturebox不会被拖到面板外部。

哇,七年后又有新的回答了...这应该能为你赢得某种徽章。不幸的是,我已经没有设置来测试你的解决方案了,但希望有人会发现你的贡献有用。 - MattyG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接