Перемещение элементов формы

184
06 мая 2018, 17:59

Вопрос из серии "помогите загуглить".

Есть панель, в которой есть несколько элементов (допустим кнопок) которые растянуты по ширине и следуют сверху-вниз.

Мне нужно добавить возможность перетаскивания одного элемента на место другого, а так же, пока юзер будет удерживать элемент, другие должны заранее смещаться. Кароче говоря, логика как у иконок на рабочем столе телефона.

Как загуглить подобный гайд я не предсталяю.

Так же крайне важно знать, какую позицию в списке занимает элемент.

Без разницы, будет это на WinForms или на WPF.

Answer 1

Полностью законченный пример на Windows Forms.

using System.Drawing;
using System.Windows.Forms;
namespace WinFormApp1
{
    public partial class Form1 : Form
    {
        TableLayoutPanel tableLayoutPanel;
        public Form1()
        {
            //InitializeComponent();
            Width = 500;
            tableLayoutPanel = new TableLayoutPanel
            {
                Parent = this,
                Dock = DockStyle.Top,
                AllowDrop = true,
                ColumnCount = 5,
                Height = 200
            };
            for (int i = 0; i < 15; i++)
            {
                var button = new Button { Parent = tableLayoutPanel, Text = "Button" + i };
                button.MouseDown += Button_MouseDown;
                button.MouseMove += Button_MouseMove;
                button.MouseUp += Button_MouseUp;
                button.MouseClick += Button_MouseClick;
            }
            tableLayoutPanel.DragOver += TableLayoutPanel_DragOver;
        }
        private void Button_MouseDown(object sender, MouseEventArgs e)
        {
            ((Button)sender).Tag = new object();
        }
        private void Button_MouseMove(object sender, MouseEventArgs e)
        {
            var button = (Button)sender;
            if (button.Tag != null)
                button.DoDragDrop(sender, DragDropEffects.Move);
        }
        private void Button_MouseUp(object sender, MouseEventArgs e)
        {
            ((Button)sender).Tag = null;
        }
        private void Button_MouseClick(object sender, MouseEventArgs e)
        {
            Text = ((Control)sender).Text;
        }
        private void TableLayoutPanel_DragOver(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent(typeof(Button)))
                return;
            e.Effect = e.AllowedEffect;
            var draggedButton = (Button)e.Data.GetData(typeof(Button));
            var pt = tableLayoutPanel.PointToClient(new Point(e.X, e.Y));
            var button = (Button)tableLayoutPanel.GetChildAtPoint(pt);
            if (button != null)
            {
                var pos = tableLayoutPanel.GetPositionFromControl(button);
                tableLayoutPanel.Controls.Add(draggedButton, pos.Column, pos.Row);
                draggedButton.Tag = null;
            }
        }
    }
}
Answer 2

Здесь описывается реализация: https://docs.microsoft.com/ru-ru/dotnet/framework/wpf/advanced/walkthrough-enabling-drag-and-drop-on-a-user-control

READ ALSO
Как открыть новое окно, чтобы старое осталось активным? C# forms

Как открыть новое окно, чтобы старое осталось активным? C# forms

Нужно открыть новое окно приложения, чтобы с предыдущим можно было взаимодействоватьНигде не смог найти информацию про это

168
Помогите с кодом

Помогите с кодом

Я написал обычный калькулятор, работающий в консолиЯ хочу сделать так, чтобы, например, при записи в консоль слова "Калькулятор" заработал...

154
Ошибка подключения к БД в Debian

Ошибка подключения к БД в Debian

Не могу подключиться к базе данных на VDS(ОС Debian)

164
Соединение между клиентом и сервером WPF C#.NET

Соединение между клиентом и сервером WPF C#.NET

У меня две программы Клиент программа и Сервер программа написанные на WPF C#NET

154