为 WinForms 控件恢复 FlowLayout






3.45/5 (10投票s)
2004年10月8日
1分钟阅读

120419

1409
本文档描述了如何创建一个允许 WinForms 使用 FlowLayout 定位的 Panel。
引言
由于下一个 Visual Studio 处于 Beta 2 阶段,并且 FlowLayout 预计会在该版本中回归,这可能为时已晚,但我觉得有必要分享一下。FlowLayout 选项在 .NET WinForms 中已经缺失了一段时间。虽然我们中的许多人并不介意绝对定位,但当您想动态添加控件但又不想担心 System.Drawing.Points
或 .Top
和 .Left
属性时,它可能会变得很麻烦(或者至少令人恼火)。
背景
我目前正在实现一个缩略图视图,并且对 WinForms 中没有 FlowLayout 选项感到苦恼。在 Google 上搜索 FlowLayout 控件后,发现相关的控件非常稀少,所以我决定自己编写一个并分享给大众使用。
自从我发布这篇文章以来,我对它进行了一些增强,包括添加了一个 LayoutStyle
属性,该属性接受一个 enum
,用于 LayoutStyles.FlowLayout
或 LayoutStyles.GridLayout
。
用法
FlowLayoutPanel 是一个小型应用程序,其中包含一个自定义控件(FlowLayoutPanel.cs),它扩展了 System.Windows.Forms.Panel
并重写了
protected override void OnLayout(LayoutEventArgs levent)
以处理 Panel
的 FlowLayout 行为。
它简单直接,所有实际工作都在上面的方法中完成(代码如下)。下载包含一个来自 Visual Studio .NET 2003 的解决方案,该解决方案捆绑了一个示例应用程序和 FlowLayoutPanel
。除了添加 LayoutStyle
属性之外,它与标准 Panel
的用法没有显著差异,当然,如果将 LayoutStyle
属性设置为 LayoutStyles.FlowLayout
,则通过 this.Controls.Add(someControl)
或在设计模式下拖放控件,将自动使用 FlowLayout 特性对控件进行定位。
protected override void OnLayout(LayoutEventArgs levent)
{
if (this.LayoutStyle == LayoutStyles.FlowLayout)
{
int nextTop = 0, nextLeft = 0;
int maxHeight = 0, maxWidth = 0;
int ParentWidth;
if (this.Parent != null)
{
ParentWidth = this.Parent.Width;
}
else
{
ParentWidth = this.Width;
}
foreach(Control myControl in this.Controls)
{
myControl.Top = nextTop;
myControl.Left = nextLeft;
if (myControl.Height > maxHeight)
{
maxHeight = myControl.Height;
}
if (myControl.Width > maxWidth)
{
maxWidth = myControl.Width;
}
if ((nextLeft + myControl.Width + maxWidth) >= ParentWidth)
{
nextTop += maxHeight;
nextLeft = 0;
}
else
{
nextLeft += myControl.Width;
}
}
this.AutoScrollPosition = new System.Drawing.Point(0,0);
base.OnLayout (levent);
}