防止拖放到当前控件之外(TreeView中的TreeNodes)

时间:2012-03-26 07:53:20

标签: c# winforms drag-and-drop treeview treenode

我正在维护一个Windows应用程序,该应用程序在一个窗口中有多个表单(form1form2form3)。我现在将另一个form2form3视为黑盒子。在form1我有一个TreeView,我正在TreeView中实现拖放功能 如何防止在form1控件之外掉线?

我正在实施3个事件处理程序:

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 个答案:

答案 0 :(得分:4)

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;

答案 1 :(得分:1)

您可以检查鼠标拖动操作是否超出允许区域,如果是,则取消拖动操作。

MSDN中有一个很好的示例,它使用QueryContinueDrag事件来实现此目的。我认为您可以在解决方案的基础上使用它。

链接:DragAction Enumeration

答案 2 :(得分: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方法以及一个Rectangle对象,其大小设置为包含一堆Pictureboxes的面板的大小(代码中的“ panel1”)(代码中的“ pb”) 。新矩形的大小设置为父面板减去Picturebox的宽度和高度,其位置设置为panel1的位置减去Picturebox宽度和高度的一半。这将为您提供一个矩形,它将约束Picturebox避免在面板外被吸毒。