【发布时间】:2014-01-11 13:00:01
【问题描述】:
我已经实现了选项卡控件拖放。在哪里,当我单击选项卡控件并拖动时,会打开一个带有选项卡页数据的新表单。
问题是如果我保留 form.Show()。表单显示拖动外观并随鼠标移动。 但是,如果我使用 form.ShowDialog() 那么表单只是打开并且不会发生拖动效果。
在这种情况下,我只能在单击表单标题并再次拖动时才能拖动。 我在下面写了相同的代码。
protected override void WndProc(ref Message m)
{
if (m.Msg == NativeMethods.WM_MOVING)
{
DockUndockTabpage(m);
}
base.WndProc(ref m);
switch (m.Msg)
{
case NativeMethods.WM_MOUSEMOVE:
if (m.WParam.ToInt32() == 1)
{
if (!captured)
{
Point pt = tabControl.PointToScreen((Cursor.Position));
Point newPosition = new Point(pt.X - dragOffset.X, pt.Y - dragOffset.Y);
this.Location = newPosition;
}
NativeMethods.RECT rc = new NativeMethods.RECT(this.Bounds);
IntPtr lParam = Marshal.AllocHGlobal(Marshal.SizeOf(rc));
Marshal.StructureToPtr(rc, lParam, true);
NativeMethods.SendMessage(this.Handle, NativeMethods.WM_MOVING, IntPtr.Zero, lParam);
Marshal.FreeHGlobal(lParam);
}
break;
case NativeMethods.WM_SETCURSOR:
captured = true;
break;
default:
break;
}
}
停靠和取消停靠有两种方法,分别是To和from原始表单。
private void DockToTab()
{
if (!tabControl.TabPages.Contains(tabPageToInsert))
{
tabControl.TabPages.Insert(tabID, tabPageToInsert);
tabControl.SelectedTab = tabPageToInsert;
tabControl.Capture = true;
this.Close();
}
}
private static void UnDockFromTab()
{
if (formToShow.Visible || formToShow.IsDisposed)
return;
formToShow.tabControl.TabPages.Remove(formToShow.tabPageToInsert);
formToShow.Capture = true;
formToShow.ShowDialog();
}
请帮忙。
【问题讨论】:
-
这段代码看起来非常随机,很难看出它是如何工作的。您的用户也永远不会自己弄清楚他应该拖动选项卡控件。创建一个合理且可用的 UI,只需在标签页中添加一个查看按钮即可。
-
@HansPassant 我刚刚给出了取消停靠和停靠表单的代码的 sn-p。当用户单击 TabPage Header 并拖动它时,会打开一个新表单。我在 Tabpage Header 上添加了图像表示此标签页是可拖动的。
-
我需要知道为什么 Drag 适用于 Show() 而不适用于 ShowDialog()。如果需要,我可以让项目获得更多想法。
-
ShowDialog() 方法锁定所有事件。如果您不想停止其他表单事件,则必须使用 Show() 方法。
-
@nercan Ohh 可能这就是我无法以所需方式拖动表单的原因,因为没有正确调用内部事件..?
标签: c# winforms drag-and-drop draggable showdialog