可能有几种方法可以做到这一点。我已经尝试了一些,但没有一个是完美的。我想说我发现的最简单的方法是像 Hans 提到的那样设置 ToolStripPanel 的最大大小,并将 ToolStrip 子类化并覆盖 OnLocationChanged (或者将事件处理程序分配给 LocationChanged 而不是子类化,但是你d 必须为每个 ToolStrip 分配一个处理程序)。
public class ToolStripEx : ToolStrip
{
protected override void OnLocationChanged(EventArgs e)
{
if (this.Location.Y >= this.Parent.MaximumSize.Height)
{
this.Location = new Point(this.Location.X, 0);
}
else
{
base.OnLocationChanged(e);
}
}
}
注意:这会导致鼠标在尝试向下拖动 ToolStrip 时来回跳跃,因为位置在 在它已经改变之后被重置,所以它本质上是向下移动,然后立即向上跳。
还值得一提的是,这可能会给用户带来烦恼,尤其是如果他们故意尝试将 ToolStrip 放在新行中,所以我真的不建议这样做。但是既然你问了,那就是。
更新完整的步骤和代码:
我创建了一个新的空白 Windows 窗体项目。我在解决方案中添加了一个新文件ToolStripEx.cs,这就是里面的内容:
更新了其他面板及其Orientation
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public class ToolStripEx : ToolStrip
{
protected override void OnLocationChanged(EventArgs e)
{
if (this.Parent is ToolStripPanel)
{
ToolStripPanel parent = this.Parent as ToolStripPanel;
if (parent.Orientation == Orientation.Horizontal)
{
if (this.Location.Y != 0)
{
this.Location = new Point(this.Location.X, 0);
return;
}
}
else if (parent.Orientation == Orientation.Vertical)
{
if (this.Location.X != 0)
{
this.Location = new Point(0, this.Location.Y);
return;
}
}
}
base.OnLocationChanged(e);
}
}
}
然后我构建了解决方案,以便 ToolStripEx 类将显示在工具箱中。
然后我从工具箱中将一个普通的ToolStripContainer 放到表单上,将Dock 设置为Fill,设置颜色等。
然后我将两个ToolStripExs(带有您提到的齿轮图标)从工具箱拖到TopToolStripPanel。我设置了它们的颜色和渲染器等等。
这是Form1.cs 的样子:
更新为设置其他最大尺寸
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.toolStripContainer1.TopToolStripPanel.MaximumSize = new Size(0, toolStripEx1.Height);
this.toolStripContainer1.LeftToolStripPanel.MaximumSize = new Size(toolStripEx1.Height, 0);
this.toolStripContainer1.BottomToolStripPanel.MaximumSize = new Size(0, toolStripEx1.Height);
this.toolStripContainer1.RightToolStripPanel.MaximumSize = new Size(toolStripEx1.Height, 0);
}
}
}
注意:此代码可防止任何面板扩展其行(或列,如果它们具有 Orientation 或 Orientation.Vertical)如果您希望侧面板能够扩展,不要设置它们的最大尺寸并去掉else if parent.Orientation == Orientation.Vertical 部分。
这应该就是它的全部了。我运行了这个,ToolStripExs 在移动它们时都没有消失。
正如 Hans 所说,ToolStrip 类非常古怪,除非您根据自己的需求从头开始开发自己的控件,否则几乎任何解决您问题的方法都不会完美。
如果由于某种原因您需要扩展 ToolStripContainer 类,请将其与新的 ToolStripEx 类分开。我怀疑嵌套类会导致您仍然使用常规的 ToolStrip 而不是 ToolStripEx 类。
另一个更新 - 修复鼠标跳跃:
我在尝试摆脱鼠标光标问题时偶然发现了这一点。将此添加到 ToolStripEx 类:
protected override void OnBeginDrag(EventArgs e)
{
//base.OnBeginDrag(e);
}
奇怪的是,这似乎大大减少了工具条被拖出面板的阻力。我还没有深入研究为什么会这样,但似乎 ToolStrip 实现了自己的拖动行为,而不使用基本的拖放功能,并且通过覆盖 OnBeginDragDrop,ToolStrip 仅使用其自定义行为,这使得鼠标的行为更好拖动时。