我在Visual Studio2005中使用.net 2.0,并尝试在窗体顶部添加两个不同的工具条,以便它们并排显示。我希望它像Word 2003一样,您可以将多个工具条添加到同一行中,并使它们彼此对齐显示,而不是为每个工具条指定一行。
因此,我添加了一个ToolStripPanel并将其停靠在表单的顶部(我没有使用ToolStripContainer,因为我不需要所有额外的面板;我只需要顶部的面板)。我添加了两个工具条,并将它们的Stretch属性设置为False。我可以让它们并排出现在设计器窗口中,但在运行时,ToolStripPanel会将工具条分开,并为每个工具条提供自己的专用行。似乎雪上加霜的是,当我停止调试并返回到设计器时,我发现设计器也将工具条移动到自己的行!我是不是做错了什么?
我已经搜索了一整天,发现了一些关于控件对象的信息,但我没有找到一种简单的方法来向它添加工具条(即它没有ToolStripPanelRow.Controls.Add方法或类似的东西),它只有一个返回控件对象数组的ToolStripPanelRow ()属性,并且我没有太多的机会尝试向该数组添加项。我还找到了一些关于ToolStripPanel.Join方法的文档,听起来它应该可以完成这项工作,所以我尝试了所有3个重载,但它们并不像广告中所说的那样工作。无论我做什么或尝试哪个选项,它总是将新的工具条添加到面板顶部的它自己的行上,并将其他所有内容向下推。
为了完全公开,我应该警告你,我已经将ToolStripPanel和其中一个工具条添加到基类窗体中,并且我正在尝试将另一个工具条添加到继承自基类窗体的子类窗体中。基类表单中的ToolStripPanel和ToolStrip都被声明为“受保护的朋友”,所以这应该是可行的。正如我所提到的,子类窗体的设计器窗口将允许我这样做(至少,在一段时间内)。
如果有人能帮我解决这个问题,或者至少解释一下为什么它不能工作,我将不胜感激。
发布于 2009-01-22 16:36:56
我创建了一个自定义的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 Example的,针对ToolStripPanels进行了修复)
怀兹芬
发布于 2009-10-26 14:35:24
System.Windows.Forms.FlowLayoutPanel可以完成这项工作。
只需按正确的顺序将ToolStrip控件放入其中即可。
发布于 2009-03-03 15:14:49
我认为在您的情况下,只需将ToolStrip上的LayoutStyle设置为ToolStripLayoutStyle.HorizontalStackWithOverflow就可以了,而不需要您自己的自定义LayoutEngine。
我在类似的主题上询问了一个different question,关于如何处理动态项目的布局,以便更好地控制溢出。
https://stackoverflow.com/questions/403769
复制相似问题