C# Windows Forms 如何使控件的位置和大小与其父容器保持相对恒定?
C# Windows Forms How to keep control's location and size relatively constant to its parent container?
我多么需要它:
码头:
基本上我不想把它停靠在任何一边。
四面锚定:
主播None:
它确实使位置保持相对不变,但根本不调整它们的大小。
除了修改容器 Control 的 Resize 事件并遍历我认为的所有子项之外,我别无选择。
请告诉我一个更干净的方法,谢谢。
编辑:
我将在这个容器中浮动多个控件。因此,TableLayoutView
不是这种情况的选项。
此外,在 sam 的回答中,他建议像我担心的那样手动完成这项工作。好吧,我想我将不得不那样做。
这是在容器控件的 Resize
事件上手动迭代子控件。
虽然我不满意,但我会标记为已解决。
假设您希望内部元素始终距离左边框总 window 宽度的 1%。您可以在表单初始化后计算您的实际值。
在调整大小时(有一个事件)通过计算新的距离并分配它来重新计算具体的左侧位置Left = form.Width*0.01
最终结果:
我有这个 class,它包含对容器及其 children 的引用。
Foreign DynoPanel
here holds a control inside it.
private readonly Dictionary<string, DynoPanel> children;
public Panel container;
private List<Rectangle> startingRectangles;
public DynoContainer(Control parent)
{
children = new Dictionary<string, DynoPanel>();
container = new Panel
{
Dock = DockStyle.Fill
};
parent.Controls.Add(container);
container.FindForm().ResizeBegin += OnResizeBegin;
container.Resize += ContainerOnResize;
}
这里我们在母窗体的 ResizeBegin
事件中存储容器的起始位置和大小及其 children:
private void OnResizeBegin(object sender, EventArgs eventArgs)
{
startingRectangles = new List<Rectangle>();
startingRectangles.Add(container.Bounds);
foreach (var dynoPanel in children)
startingRectangles.Add(dynoPanel.Value.self.Bounds);
}
然后根据我们计算出的新比例因子,设置children的位置和大小,在实际Resize
事件上保持初始比例:
private void ContainerOnResize(object sender, EventArgs eventArgs)
{
var scale = new PointF(
(float) container.Width/startingRectangles[0].Width,
(float) container.Height/startingRectangles[0].Height);
int index = 1;
foreach (var panel in children)
{
panel.Value.self.Location = new Point(
(int) (startingRectangles[index].X*scale.X),
(int) (startingRectangles[index].Y*scale.Y)
);
panel.Value.self.Size = new Size(
(int) (startingRectangles[index].Width*scale.X),
(int) (startingRectangles[index].Height*scale.Y)
);
index++;
}
}
我多么需要它:
码头:
基本上我不想把它停靠在任何一边。
四面锚定:
主播None:
它确实使位置保持相对不变,但根本不调整它们的大小。
除了修改容器 Control 的 Resize 事件并遍历我认为的所有子项之外,我别无选择。
请告诉我一个更干净的方法,谢谢。
编辑:
我将在这个容器中浮动多个控件。因此,TableLayoutView
不是这种情况的选项。
此外,在 sam 的回答中,他建议像我担心的那样手动完成这项工作。好吧,我想我将不得不那样做。
这是在容器控件的 Resize
事件上手动迭代子控件。
虽然我不满意,但我会标记为已解决。
假设您希望内部元素始终距离左边框总 window 宽度的 1%。您可以在表单初始化后计算您的实际值。
在调整大小时(有一个事件)通过计算新的距离并分配它来重新计算具体的左侧位置Left = form.Width*0.01
最终结果:
我有这个 class,它包含对容器及其 children 的引用。
Foreign DynoPanel
here holds a control inside it.
private readonly Dictionary<string, DynoPanel> children;
public Panel container;
private List<Rectangle> startingRectangles;
public DynoContainer(Control parent)
{
children = new Dictionary<string, DynoPanel>();
container = new Panel
{
Dock = DockStyle.Fill
};
parent.Controls.Add(container);
container.FindForm().ResizeBegin += OnResizeBegin;
container.Resize += ContainerOnResize;
}
这里我们在母窗体的 ResizeBegin
事件中存储容器的起始位置和大小及其 children:
private void OnResizeBegin(object sender, EventArgs eventArgs)
{
startingRectangles = new List<Rectangle>();
startingRectangles.Add(container.Bounds);
foreach (var dynoPanel in children)
startingRectangles.Add(dynoPanel.Value.self.Bounds);
}
然后根据我们计算出的新比例因子,设置children的位置和大小,在实际Resize
事件上保持初始比例:
private void ContainerOnResize(object sender, EventArgs eventArgs)
{
var scale = new PointF(
(float) container.Width/startingRectangles[0].Width,
(float) container.Height/startingRectangles[0].Height);
int index = 1;
foreach (var panel in children)
{
panel.Value.self.Location = new Point(
(int) (startingRectangles[index].X*scale.X),
(int) (startingRectangles[index].Y*scale.Y)
);
panel.Value.self.Size = new Size(
(int) (startingRectangles[index].Width*scale.X),
(int) (startingRectangles[index].Height*scale.Y)
);
index++;
}
}