Pat*_*ick 5 user-interface visual-studio-2005 toolstrip toolstrippanel .net-2.0
我在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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后自定义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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
需要一段时间的一件事是,更改一个ToolStrip项的位置/大小将导致布局重新触发,并重新排序控件.所以我在布局循环之前获取控件的副本.并且您无法使用AddRange(...)将项目添加到自定义面板由于某种原因 - 需要一次添加(...)它们.
希望有所帮助(它基于MSDN LayoutEngine示例,已针对ToolStripPanel修复)
Wyzfen