Запрет перетаскивания за пределы текущего элемента управления (TreeNodes в TreeView) - PullRequest
4 голосов
/ 26 марта 2012

Я поддерживаю приложение Windows, которое имеет несколько форм в одном окне (form1, form2, form3).В настоящий момент я отношусь к остальным form2 и form3 как к черным ящикам.В 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
}

form2 и form3 имеют отношение перетаскивания между ними, поэтому, когда я перетаскиваю узел из form1 в form3 по умолчанию, это разрешает перемещение (плохо).Я хочу иметь возможность предотвратить это из кода элемента управления form1.

Как я могу предотвратить падение за пределы элемента управления form1?Я посмотрел на событие _DragLeave, но не уверен, как управлять операцией без DragEventArgs.

Ответы [ 3 ]

4 голосов
/ 26 марта 2012

В объекте 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 голос
/ 22 марта 2019

Я знаю, что это старая тема, но поскольку я так и не нашел хорошего ответа на вопрос, как предотвратить перетаскивание элемента управления за пределы панели, я подумал, что добавлю решение, которое я собрал. Я использовал некоторые советы сверху и некоторые свои собственные.

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, размер которого устанавливается равным размеру панели ("panel1" в коде), содержащей группу Pictureboxes ("pb" в коде) , Размер нового прямоугольника устанавливается на родительскую панель за вычетом ширины и высоты Picturebox, а его расположение устанавливается на расположение панели1 минус половина ширины и высоты Picturebox. Это дает вам прямоугольник, который ограничит использование Picturebox за пределами панели.

1 голос
/ 26 марта 2012

Вы можете проверить, выходит ли действие перетаскивания мышью за пределы разрешенной области, и если это так, отменить действие перетаскивания.

В MSDN есть хороший пример, в котором для этой цели используется событие QueryContinueDrag.Я думаю, что вы можете использовать это на основе вашего решения.

Ссылка: Перечисление DragAction

...