我在Visual Studio 2005中使用.net 2.0,我试图在表单的顶部添加两个不同的工具条,以便它们并排显示.我希望它像Word 2003一样,您可以在同一行中添加多个工具条并使它们彼此一致,而不是为每个工具条专用一行.
所以我添加了一个ToolStripPanel并将其停靠在表单的顶部(我没有使用ToolStripContainer,因为我不需要所有额外的面板;我只需要顶部的那个).我添加了两个工具条并将其Stretch属性设置为False.我可以将它们并排显示在设计器窗口中,但在运行时,ToolStripPanel会分离工具条并为每个工具条提供自己的专用行.好像要侮辱伤害,当我停止调试并返回设计师时,我发现设计师正在将工具条移动到他们自己的行!我在这里做错了吗?
我一直在谷歌搜索并找到一些关于ToolStripPanelRow对象的信息,但是我没有看到向它添加工具条的简单方法(即它没有ToolStripPanelRow.Controls.Add方法或类似的东西),所有它有一个Controls()属性,返回一个控件对象Array,我没有太多运气试图向该数组添加项目.我还发现了一些关于ToolStripPanel.Join方法的文档,这听起来应该可以完成这项工作,所以我尝试了所有3次重载,但它们不像宣传的那样工作.无论我做什么或我尝试哪些选项,它总是将新的工具条添加到面板顶部的自己的行上,并将其他所有内容向下推.
为了完全公开,我应该警告你我有ToolStripPanel和一个添加到基类表单的工具条,我试图将其他工具条添加到继承自baseclass表单的子类表单.基类表单中的ToolStripPanel和ToolStrip都声明为"受保护的朋友",因此这应该有效.正如我所提到的,子类窗体的设计器窗口将允许我这样做(至少,一段时间).
如果有人能帮我解决这个问题,或者至少可以解释为什么不这样做,我将非常感激.
我创建了一个自定义ToolStripPanel,以便我可以重载LayoutEngine;
using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.Layout; namespace CustomGUI { class CustomToolStripPanel : ToolStripPanel { private LayoutEngine _layoutEngine; public override LayoutEngine LayoutEngine { get { if (_layoutEngine == null) _layoutEngine = new CustomLayoutEngine(); return _layoutEngine; } } public override Size GetPreferredSize(Size proposedSize) { Size size = base.GetPreferredSize(proposedSize); foreach(Control control in Controls) { int newHeight = control.Height + control.Margin.Vertical + Padding.Vertical; if (newHeight > size.Height) size.Height = newHeight; } return size; } } }
然后自定义LayoutEngine布局ToolStrips;
using System.Drawing; using System.Windows.Forms; using System.Windows.Forms.Layout; namespace CustomGUI { class CustomLayoutEngine : LayoutEngine { public override bool Layout(object container, LayoutEventArgs layoutEventArgs) { Control parent = container as Control; Rectangle parentDisplayRectangle = parent.DisplayRectangle; Control [] source = new Control[parent.Controls.Count]; parent.Controls.CopyTo(source, 0); Point nextControlLocation = parentDisplayRectangle.Location; foreach (Control c in source) { if (!c.Visible) continue; nextControlLocation.Offset(c.Margin.Left, c.Margin.Top); c.Location = nextControlLocation; if (c.AutoSize) { c.Size = c.GetPreferredSize(parentDisplayRectangle.Size); } nextControlLocation.Y = parentDisplayRectangle.Y; nextControlLocation.X += c.Width + c.Margin.Right + parent.Padding.Horizontal; } return false; } } }
需要一段时间的一件事是,更改一个ToolStrip项的位置/大小将导致布局重新触发,并重新排序控件.所以我在布局循环之前获取控件的副本.并且您无法使用AddRange(...)将项目添加到自定义面板由于某种原因 - 需要一次添加(...)它们.
希望有所帮助(它基于MSDN LayoutEngine示例,已针对ToolStripPanel修复)
Wyzfen