XtraTabControl(DEV中选项卡)分页实现拖拽 效果
用到的命名空间是:
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; }