XtraTabControl(DEV中选项卡)分页实现拖拽 效果

时间:2021-12-10 15:07:35
用到的命名空间是:
    using DevExpress.XtraTab;
using DevExpress.XtraTab.ViewInfo;
用到的变量:
    private Rectangle rectDragBoxFromMouseDown;
private bool isDragging = false;
private Point dragOffset = Point.Empty;
创建所用到的函数:
    private void CalcRectDragBox(int x, int y)
{
// Remember the point where the mouse down occurred. The DragSize indicates
// the size that the mouse can move before a drag event should be started.
Size dragSize = SystemInformation.DragSize;
// Create a rectangle using the DragSize, with the mouse position being
// at the center of the rectangle.
rectDragBoxFromMouseDown = new Rectangle(new Point((int)x - (dragSize.Width / 2), (int)y - (dragSize.Height / 2)), dragSize);
}
private int FindIndex(XtraTabPage page)
{
int i = 0;
while (i < xtcMain.TabPages.Count)
{
if (xtcMain.TabPages[i].Equals(page))
{
return i;
}
i += 1;
}
return -1;
}
在 DragOver 事件中的code:
    XtraTabHitInfo hinfo = default(XtraTabHitInfo);
XtraTabPage hoverTab = default(XtraTabPage);
XtraTabPage dragTab = default(XtraTabPage);
XtraTabPage selTab = default(XtraTabPage);
XtraTabPage repTab = default(XtraTabPage);
//
int itemDragIndex = 0;
int dropLocationIndex = 0;
//
// get the tab we are hovering over.
hinfo = xtcMain.CalcHitInfo(xtcMain.PointToClient(new Point(e.X, e.Y)));
//
if ((hinfo.Page != null))
{
hoverTab = hinfo.Page;
//Make sure there is a TabPage being dragged.
if (e.Data.GetDataPresent(typeof(XtraTabPage)))
{
e.Effect = DragDropEffects.Move;
dragTab = (XtraTabPage)e.Data.GetData(typeof(XtraTabPage));
// can't use the TabIndex on the control because it changes
// when we move the tab page.
itemDragIndex = FindIndex(dragTab);
dropLocationIndex = FindIndex(hoverTab);
//Don't do anything if we are hovering over ourself.
if (itemDragIndex != dropLocationIndex)
{
selTab = xtcMain.TabPages[itemDragIndex];
repTab = xtcMain.TabPages[dropLocationIndex];
//
xtcMain.TabPages.Move(dropLocationIndex, selTab);
xtcMain.TabPages.Move(itemDragIndex, repTab);
xtcMain.SelectedTabPage = selTab;
}
}
}
else
{
e.Effect = DragDropEffects.None;
}
在 MouseDown 事件中的code:
    CalcRectDragBox(e.X, e.Y);


// Handle Mouse move only if left button is pressed.
if (e.Button == MouseButtons.Left)
{
// If the mouse moves outside the rectangle, start the drag.
if (!rectDragBoxFromMouseDown.Equals(Rectangle.Empty) & !rectDragBoxFromMouseDown.Contains(e.X, e.Y))
{
isDragging = true;
dragOffset = new Point(e.X, e.Y);
Invalidate();
// Proceed with the drag and drop.
DragDropEffects dropEffect = DoDragDrop(xtcMain.SelectedTabPage, DragDropEffects.Move);
// Reset the drag box to avoid reentry of drag.
CalcRectDragBox(e.X, e.Y);
isDragging = false;
dragOffset = Point.Empty;
Invalidate();
}
}

如果你有不同大小的标签,张贴的代码将导致快如闪电的标签之间切换,如果您对重叠的区域的大小不同悬停。 为了防止这种情况,我只是说在dragOver处理一个简单的标志,忽略未来DragOver事件。 在上面的DragOver里面相应的 位置加入这个标志ignoreNextDrag,具体代码如下:
    if (itemDragIndex != dropLocationIndex && !ignoreNextDrag)
{
ignoreNextDrag = true;
selTab = tabControlClientModules.TabPages[itemDragIndex];
repTab = tabControlClientModules.TabPages[dropLocationIndex];
//
tabControlClientModules.TabPages.Move(dropLocationIndex, selTab);
tabControlClientModules.TabPages.Move(itemDragIndex, repTab);
tabControlClientModules.SelectedTabPage = selTab;
}
else
{
ignoreNextDrag = false;

}