How to make TabPages draggable?

前端 未结 3 1780
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-13 07:42

I\'d like to enable user to rearrange TabPages order by dragging and dropping. Moreover it\'d be cool to enable user to drag TabPages from one TabControl to another. Both th

3条回答
  •  醉酒成梦
    2021-01-13 08:40

    Here is a way to also enable dragging between different TAB controls. This also works when the second control has no tabs yet (though overriding Wndproc). Based on the answer of bruce965, and info found here. Hope this is helpful for anyone looking for draggable tabs!

    namespace Utilities.Windows.Forms
    {
        public class DraggableTabControl : TabControl
        {
            private TabPage predraggedTab;
    
            private const int WM_NCHITTEST = 0x84;
            private const int HTTRANSPARENT = -1;
            private const int HTCLIENT = 1;
    
            public DraggableTabControl()
            {
                this.AllowDrop = true;
            }
    
            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                if (m.Msg == WM_NCHITTEST)
                {
                    if (m.Result.ToInt32() == HTTRANSPARENT)
                        m.Result = new IntPtr(HTCLIENT);
                }
            }
    
            protected override void OnMouseDown(MouseEventArgs e)
            {
    
                predraggedTab = getPointedTab();
    
                base.OnMouseDown(e);
            }
    
            protected override void OnMouseUp(MouseEventArgs e)
            {
                base.OnMouseUp(e);
            }
    
            protected override void OnMouseMove(MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left && predraggedTab != null)
                    this.DoDragDrop(predraggedTab, DragDropEffects.Move);
    
                base.OnMouseMove(e);
            }
    
            protected override void OnDragDrop(DragEventArgs drgevent)
            {
                TabPage draggedTab = (TabPage)drgevent.Data.GetData(typeof(TabPage));
    
                if (draggedTab.Parent != this)
                {
                    draggedTab.Parent = this;
                    this.SelectedTab = draggedTab;
                }
    
                predraggedTab = null;
    
                base.OnDragDrop(drgevent);
            }
    
            protected override void OnDragOver(DragEventArgs drgevent)
            {
                TabPage draggedTab = (TabPage)drgevent.Data.GetData(typeof(TabPage));
                TabPage pointedTab = getPointedTab();
    
                if (draggedTab == predraggedTab && pointedTab != null)
                {
                    drgevent.Effect = DragDropEffects.Move;
    
                    if (pointedTab != draggedTab)
                        swapTabPages(draggedTab, pointedTab);
                }
                else if (draggedTab != null && draggedTab.Parent != this)
                {
                    drgevent.Effect = DragDropEffects.Move;
                }
    
                base.OnDragOver(drgevent);
            }
    
            private TabPage getPointedTab()
            {
                for (int i = 0; i < this.TabPages.Count; i++)
                    if (this.GetTabRect(i).Contains(this.PointToClient(Cursor.Position)))
                        return this.TabPages[i];
                return null;
            }
    
            private void swapTabPages(TabPage src, TabPage dst)
            {
                int srci = this.TabPages.IndexOf(src);
                int dsti = this.TabPages.IndexOf(dst);
    
                this.TabPages[dsti] = src;
                this.TabPages[srci] = dst;
    
                if (this.SelectedIndex == srci)
                    this.SelectedIndex = dsti;
                else if (this.SelectedIndex == dsti)
                    this.SelectedIndex = srci;
    
                this.Refresh();
            }
        }
    }
    

提交回复
热议问题