【问题标题】:How to prevent ToolStrip from docking in another ToolStripContainer?如何防止 ToolStrip 停靠在另一个 ToolStripContainer 中?
【发布时间】:2008-11-18 04:56:32
【问题描述】:

我有一个 MDI 应用程序,它允许我打开不同类型的子窗口。我可以打开相同类型的子窗口的多个(但不同的)实例。 (示例:我可以打开 3 个子窗口类型 A 的实例和 2 个子窗口类型 B 的实例。所有 5 个窗口都是不同的实体,除非用户明确将相同的数据拖到多个窗口上,否则它们不会共享数据。)每个子窗口有一个带有一个或多个 ToolStrips 的 ToolStripContainer。如何预防:

  1. 用户是否将 ToolStrip 从 A 类型的子窗口拖动到 B 类型的子窗口中的 ToolStripContainer?
  2. 用户是否将 ToolStrip 从子窗口 A 的一个实例拖动到同一类型窗口的另一个实例中的 ToolStripContainer?

我试图阻止用户将 ToolStrip 从 A 类型的实例 1 拖动到 A 类型的实例 2,在实例 2 上选择一些东西,然后单击工具栏上的一个按钮,结果却发生了一些奇怪的事情其他一些窗口。同样,将 ToolStrip 从 A 类型的窗口拖动到 B 类型的窗口是没有意义的——这些操作不适用于该类型,但对用户来说,一切都很好,因为我让他们这样做拖累。

是像为 ControlAdded 事件添加我自己的处理程序一样简单,还是有更好的方法来做到这一点?我在 .NET 3.0 中使用 WinForms。

编辑:重现的步骤

  1. 创建一个新的 Windows 应用程序项目。
  2. 添加新的用户控件。为控件提供一个 ToolStripContainer,其中包含一个带有单个按钮的 ToolStrip。
  3. 重复第 2 步,为您提供一个 UserControl2 类。
  4. 编译解决方案,使 UserControl1 和 UserControl2 显示在您的工具箱中。
  5. 将 UserControl1 和 UserControl2 拖到窗体上。设置边界,以便您知道边界在哪里。
  6. 运行应用程序。
  7. 现在可以将 ToolStrip 从 UserControl1 中的容器拖放到 UserControl2 中的容器中(在 UC1 中保留零个 ToolStrip,在 UC2 中保留两个 ToolStrip。)
  8. 现在假设您只能访问 UserControl1 中的代码。如何防止用户将 ToolStrip 拖出 ToolStripContainer 实例?

【问题讨论】:

  • 我试图重现您遇到的问题,但我似乎无法让它工作。一旦我创建了相同表单的两个实例,我一开始就无法将工具栏从一个拖到另一个
  • 查看回购步骤。只有一个带有两个单独用户控件的表单实例,而不是两个表单实例。

标签: c# .net winforms mdi toolstrip


【解决方案1】:

这感觉像是一个 hack,但它确实有效(有点)(抱歉,vb.net 不是 c#):

Public Class UserControl2

    Private Sub tsMainMenu_BeginDrag(ByVal sender As Object, ByVal e As System.EventArgs) Handles tsMainMenu.BeginDrag

        tsMainMenu.Tag = tsMainMenu.Parent

    End Sub

    Private Sub ToolStrip1_EndDrag(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsMainMenu.EndDrag


        If Not tsMainMenu.Parent.Parent.Equals(CType(tsMainMenu.Tag, ToolStripPanel).Parent) Then

            CType(ToolStrip1.Tag, ToolStripPanel).Controls.Add(tsMainMenu)
        End If

    End Sub

End Class

简单地说;当控件完成拖动时,如果其父 ToolStripContainer 与开始拖动时不同,则将工具条移回原来的位置。

我确信这可以滚动到一个控件中,这样您就不必为每个工具栏都编写它。

编辑: 您可以将所有这些代码放入从 ToolStripContainer 继承的控件中,并让它为您完成所有工作,这意味着一个很好的封装解决方案。

【讨论】:

  • 只有在您可以访问工具条的所有代码时才有效。请参阅提交中我的重现步骤的第 8 步。 (实际上我不确定这是否有效:看起来您正在将事件处理程序附加到 ToolStrip.EndDrag 事件。内置处理程序仍将运行并执行放置操作。如果您拥有所有工具栏源代码,但我没有。)
【解决方案2】:

您是否尝试过使用 ToolStripContainer 的 DragEnter 和 DragLeave 事件来识别拖过容器的 ToolStrip 是接受还是拒绝?

【讨论】:

  • 只有在您拥有并有权访问所有 ToolStripContainers 时才有效。请参阅上面的 A/B 示例。
  • 我试图重现您的问题,但 ToolStrips 不允许将它们从一个实例拖到另一个实例(即使是同一类型)。所以你要求的应该是默认行为......
  • 我可以重现它(按照你的步骤)
猜你喜欢
  • 1970-01-01
  • 2011-11-11
  • 2011-12-01
  • 1970-01-01
  • 2017-02-28
  • 2013-10-15
  • 2013-10-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多