以前在做项目的时候,窗体中使用几个不同的Panel分割成不同部分,然后用Splitter实现动态调整大小,但发现一切并不是象想象中的那么容易,经常发现Panel与Splitter没有起到应当有的作用,屏幕乱作一团(Delphi中从来没有出现过这类问题)。
从网上查了不少的资料,关于这方面的太少了。最后从http://www.dotnet247.com/247reference/msgs/16/84807.aspx看到了有人提问,但没好的解答。经过自己研究后,发现Dock能够正常工作居然与对象的创建顺序有关,可这些对象的创建顺序是由.net自动生成的(与控件放入的顺序有关),一旦顺序错误,屏幕就乱了。发现问题所在后,我在网上给出了我的解决办法。现在把它搬过来,供大家参考:
出现问题的代码:
using System;
using System.Windows.Forms;
internal class DockTest : Form
{
internal DockTest()
{
Width = 200;
Height = 200;
// Panel to fill in the space to the top, will get resized
// as the bottom panel moves.
Panel topPanel = new Panel();
topPanel.Dock = DockStyle.Fill;
topPanel.BorderStyle = BorderStyle.Fixed3D;
topPanel.Height = 100;
Label l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Top Panel";
l.AutoSize = true;
topPanel.Controls.Add(l);
// Panel to be anchored at the bottom and docked to the bottom
// Needs to be a minimum size and move when the bottom edge
// is resized.
Panel nextPanel = new Panel();
nextPanel.Dock = DockStyle.Bottom;
nextPanel.Anchor = AnchorStyles.Bottom
| AnchorStyles.Right
| AnchorStyles.Left;
nextPanel.BorderStyle = BorderStyle.Fixed3D;
nextPanel.Height = 100;
l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Next Panel";
l.AutoSize = true;
nextPanel.Controls.Add(l);
// Splitter between the panels
Splitter topBottomSplitter = new Splitter();
topBottomSplitter.Dock = DockStyle.Bottom;
// Add in reverse order (sigh)
Controls.Add(nextPanel);
Controls.Add(topBottomSplitter);
Controls.Add(topPanel);
}
[STAThread]
public static void Main(string[] args)
{
System.Windows.Forms.Application.Run(new DockTest());
}
}
using System.Windows.Forms;
internal class DockTest : Form
{
internal DockTest()
{
Width = 200;
Height = 200;
// Panel to fill in the space to the top, will get resized
// as the bottom panel moves.
Panel topPanel = new Panel();
topPanel.Dock = DockStyle.Fill;
topPanel.BorderStyle = BorderStyle.Fixed3D;
topPanel.Height = 100;
Label l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Top Panel";
l.AutoSize = true;
topPanel.Controls.Add(l);
// Panel to be anchored at the bottom and docked to the bottom
// Needs to be a minimum size and move when the bottom edge
// is resized.
Panel nextPanel = new Panel();
nextPanel.Dock = DockStyle.Bottom;
nextPanel.Anchor = AnchorStyles.Bottom
| AnchorStyles.Right
| AnchorStyles.Left;
nextPanel.BorderStyle = BorderStyle.Fixed3D;
nextPanel.Height = 100;
l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Next Panel";
l.AutoSize = true;
nextPanel.Controls.Add(l);
// Splitter between the panels
Splitter topBottomSplitter = new Splitter();
topBottomSplitter.Dock = DockStyle.Bottom;
// Add in reverse order (sigh)
Controls.Add(nextPanel);
Controls.Add(topBottomSplitter);
Controls.Add(topPanel);
}
[STAThread]
public static void Main(string[] args)
{
System.Windows.Forms.Application.Run(new DockTest());
}
}
经过调整对象生成顺序后的代码:
using System;
using System.Windows.Forms;
internal class DockTest : Form
{
internal DockTest()
{
Width = 200;
Height = 200;
// Panel to be anchored at the bottom and docked to the bottom
// Needs to be a minimum size and move when the bottom edge
// is resized.
Panel nextPanel = new Panel();
nextPanel.BorderStyle = BorderStyle.Fixed3D;
nextPanel.Dock = DockStyle.Bottom;
nextPanel.Height = 100;
Label l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Next Panel";
l.AutoSize = true;
nextPanel.Controls.Add(l);
// Splitter between the panels
Splitter topBottomSplitter = new Splitter();
topBottomSplitter.Dock = DockStyle.Bottom;
// Panel to fill in the space to the top, will get resized
// as the bottom panel moves.
Panel topPanel = new Panel();
topPanel.BorderStyle = BorderStyle.Fixed3D;
topPanel.Dock = DockStyle.Fill;
topPanel.Height = 100;
l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Top Panel";
l.AutoSize = true;
topPanel.Controls.Add(l);
// Add in reverse order (sigh)
Controls.Add(topPanel);
Controls.Add(topBottomSplitter);
Controls.Add(nextPanel);
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new DockTest());
}
}
using System.Windows.Forms;
internal class DockTest : Form
{
internal DockTest()
{
Width = 200;
Height = 200;
// Panel to be anchored at the bottom and docked to the bottom
// Needs to be a minimum size and move when the bottom edge
// is resized.
Panel nextPanel = new Panel();
nextPanel.BorderStyle = BorderStyle.Fixed3D;
nextPanel.Dock = DockStyle.Bottom;
nextPanel.Height = 100;
Label l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Next Panel";
l.AutoSize = true;
nextPanel.Controls.Add(l);
// Splitter between the panels
Splitter topBottomSplitter = new Splitter();
topBottomSplitter.Dock = DockStyle.Bottom;
// Panel to fill in the space to the top, will get resized
// as the bottom panel moves.
Panel topPanel = new Panel();
topPanel.BorderStyle = BorderStyle.Fixed3D;
topPanel.Dock = DockStyle.Fill;
topPanel.Height = 100;
l = new Label();
l.Dock = DockStyle.Top;
l.Text = "Top Panel";
l.AutoSize = true;
topPanel.Controls.Add(l);
// Add in reverse order (sigh)
Controls.Add(topPanel);
Controls.Add(topBottomSplitter);
Controls.Add(nextPanel);
}
[STAThread]
public static void Main(string[] args)
{
Application.Run(new DockTest());
}
}
大家可以自己试试。
注:.net 2005好像解决了这个问题(提供了一个新控件),但我还没有来得及尝试。