为什么在动态创建的嵌套组件中不支持Anchor属性?

时间:2013-12-12 06:37:25

标签: c# winforms user-interface

首先让我说我没有做过很多Windows窗体开发 - 如果我可能会犯一个明显的错误,请不要犹豫,提及它。

重现我的问题的步骤:

  • 使用VS 2010或VS 2012
  • 创建新的C#Windows窗体项目
  • 使用VS表单设计器,将三个FlowLayoutPanel组件添加到表单
  • 将每个FlowLayoutPanel设置为与表单具有相同的高度,并且大约为表单宽度的1/3
  • 定位每个FlowLayoutPanel,使它们不会水平重叠,共同消耗表格的整个区域。

  • 最左边的FlowLayoutPanel配置为具有顶部,底部,左侧的锚点

  • 中间FlowLayoutPanel配置为具有顶部,底部的锚点
  • 最右边的FlowLayoutPanel配置为具有顶部,底部,右侧的锚点

为Form_Shown添加一个事件:

private void Form1_Shown(object sender, EventArgs e)
{
  Panel p = new Panel();
  p.BorderStyle = BorderStyle.FixedSingle;
  p.Width = 200;
  p.Height = 100;

  Label label1 = new Label();
  label1.BorderStyle = BorderStyle.FixedSingle;
  label1.Text = "Hello";
  label1.Anchor = AnchorStyles.Top;

  Label label2 = new Label();
  label2.BorderStyle = BorderStyle.FixedSingle;
  label2.Text = "World!";
  label2.Anchor = AnchorStyles.Bottom;

  p.Controls.Add(label1);
  p.Controls.Add(label2);

  middleFlow.Controls.Add(p); // add to the center most FlowLayoutPanel on Form1
}

结果似乎是label1被放置在label2的顶部,尽管label2被添加到第二位。此外,锚点值似乎被忽略(因为当我打算将它们分别锚定到Panel组件的顶部和底部时,label1覆盖label2)

如果我使用Dock属性而不是Anchor属性,则行为符合要求。为什么Anchor属性在这种情况下不起作用?

此外,有没有办法将组件锚定到其他组件?我注意到,当我在运行时增加窗体的大小时,会出现面板之间的水平“间隙”。理想情况下,我希望面板能够一起生长,防止它们之间水平间隙/空白?

提前感谢任何建议或提示。

2 个答案:

答案 0 :(得分:0)

我希望你提到的行为完全正确。

Anchor属性只告诉父容器标签应该粘贴 到了父母。在您的情况下,AnchorStyles.Top意味着将标签贴在顶部,如果父母移动或调整大小,则将其留在那里。

您没有指定标签的尺寸或位置,因此两者都重叠。 当添加到middleFlow.Controls时,控件的z顺序是从订单隐式创建的。您可以使用VS表单设计器进行检查。选择"带到前面"或者"发送回来"并观察x.designer.cs如何变化 为什么它是相反的顺序是一个小的.net秘密。解决方法是更改​​顺序。有时手动操作比设计师更容易。

答案 1 :(得分:0)

我仍然开始学习c#和winforms,所以以下可能不是最佳的,但它可以满足你的需要。

使用Dock = Top处理标签。注意,切换标签使得label1位于label2的顶部,即,最后注册label1按下已经注册的label2。

三个面板的定位是在没有锚点和底座的情况下完成的,其中包含用于调整大小的事件处理程序。之后设置表单的大小会引发resize事件。着色以查看组件。

using System;
using System.Drawing;
using System.Windows.Forms;


public class ThreePanel : Form {

  FlowLayoutPanel  leftFlow;
  FlowLayoutPanel  middleFlow;
  FlowLayoutPanel  rightFlow;

  public ThreePanel(){


    leftFlow = new FlowLayoutPanel() {
      BackColor = Color.Yellow
    };

    middleFlow = new FlowLayoutPanel() {
      BackColor = Color.LightGreen
    };

    rightFlow = new FlowLayoutPanel() {
      BackColor = Color.LightBlue
    };

    this.Controls.Add(rightFlow);
    this.Controls.Add(middleFlow);
    this.Controls.Add(leftFlow);

    this.Load += (s,e)=>Form1_Shown(s,e);
    this.Resize += (s,e)=>{ 
      int w=this.Width/3; 
      leftFlow.Width=middleFlow.Width
          =rightFlow.Width=w;
      leftFlow.Height=middleFlow.Height
          =rightFlow.Height=this.Height;
      leftFlow.Location=new Point(0,0);
      middleFlow.Location=new Point(w,0);
      rightFlow.Location=new Point(2*w,0);
    };

    this.Size = new Size(750,450);

  }

  private void Form1_Shown(object sender, EventArgs e)
  {
    Panel p = new Panel() {
      BorderStyle = BorderStyle.FixedSingle,
      Width = 200,
      Height = 100,
      BackColor = Color.Fuchsia,
    };

    Label label1 = new Label() {
      BorderStyle = BorderStyle.FixedSingle,
      Text = "Hello",
      Dock = DockStyle.Top
    };

    Label label2 = new Label() {
      BorderStyle = BorderStyle.FixedSingle,
      Text = "World!",
      Dock = DockStyle.Top
    };

    p.Controls.Add(label2);
    p.Controls.Add(label1);

    // add to the center most FlowLayoutPanel on Form1
    middleFlow.Controls.Add(p); 
  }

  public static void Main()
  {
    Application.Run(new ThreePanel());
  }
}