TabControl のタブをドラッグアンドドロップで入れ替えできるようにする
自分で作っているC#アプリケーションでタブを移動させたくなったが、標準のタブコントロールでは
タブを移動させることが出来ない。そこで
http://watcher.moe-nifty.com/memo/2009/02/ctabcontrol-b32.html
のソースを改変して作ってみた。
//タブをドラッグで移動できるようにしたクラス。
class TabControlEx : TabControl
{
private int mouseDownPointX = 0;
private int mouseDownPointY = 0;
private Rectangle dragBoxFromMouseDown = Rectangle.Empty;public TabControlEx()
{
AllowDrop = true;
ClearDragTarget();
}protected override void OnDragOver(System.Windows.Forms.DragEventArgs e)
{
base.OnDragOver(e);//■イベントが起きた位置をクライアント座標ポイントptに変換する.
Point pt = PointToClient(new Point(e.X, e.Y));//■ptからhovering overタブを得る.
TabPage hoverTab = GetTabPageByTab(pt);//■タブがキチンと取れているかどうかで条件分岐
if (hoverTab != null && e.Data.GetDataPresent(typeof(TabPage)))
{
//タブが取得できた場合の処理
e.Effect = DragDropEffects.Move;
TabPage draggedTab = (TabPage)e.Data.GetData(typeof(TabPage));int srcTabIndex = FindIndex(draggedTab);
int dstTabIndex = FindIndex(hoverTab);if (srcTabIndex != dstTabIndex)
{
this.SuspendLayout();//★これ大事
TabPage tmp = TabPages[srcTabIndex];
TabPages[srcTabIndex] = TabPages[dstTabIndex];
TabPages[dstTabIndex] = tmp;SelectedTab = draggedTab;
this.ResumeLayout();//★これも大事
}
}
else
{
//タブが取得できなかった場合の処理
e.Effect = DragDropEffects.None;//何もしなくて良い
}
}protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);if (dragBoxFromMouseDown != Rectangle.Empty
&&
!dragBoxFromMouseDown.Contains(e.X, e.Y))
{
if (this.TabCount <= 1)
{
return;
}Point pt = new Point(mouseDownPointX, mouseDownPointY);
TabPage tp = GetTabPageByTab(pt);if (tp != null)
{
DoDragDrop(tp, DragDropEffects.All);
}
}
}protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
ClearDragTarget();
}protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
ClearDragTarget();
}private void ClearDragTarget()
{
dragBoxFromMouseDown = Rectangle.Empty;
mouseDownPointX = 0;
mouseDownPointY = 0;
}private void SetupDragTarget(int x, int y)
{
Size dragSize = SystemInformation.DragSize;dragBoxFromMouseDown =
new Rectangle(new Point(x - (dragSize.Width / 2),
y - (dragSize.Height / 2)), dragSize);
mouseDownPointX = x;
mouseDownPointY = y;
}protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
ClearDragTarget();if (e.Button != MouseButtons.Left
||
e.Clicks >= 2)
return;SetupDragTarget(e.X, e.Y);
}//■GetTabPageByTab : Point --> TabPage + {null}
private TabPage GetTabPageByTab(Point pt)
{
for (int i = 0; i < TabPages.Count; i++)
{
if (GetTabRect(i).Contains(pt))
{
return TabPages[i];
}
}return null;
}//■FindIndex: TabPage --> Int + { null }
private int FindIndex(TabPage page)
{
for (int i = 0; i < TabPages.Count; i++)
{
if (TabPages[i] == page)
{
return i;
}
}
return -1;
}
}