WinForms(.NET 2)问题:
当调整父窗体(或面板)的大小时,是否有办法将元素保持在比例距离?
我可以在此范围内使用Graphics.TransformPoints
或Graphics.TransformVectors
吗?怎么样。
alt text http://lh5.ggpht.com/_1TPOP7DzY1E/S_-QWNbBoqI/AAAAAAAADN8/cNSRTfxLEoI/s800/Capture3.gif
编辑:
TableLayoutPanel 不起作用,因为应该接受叠加元素。
EDIT2:
这是我的代码:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Microsoft.VisualBasic.PowerPacks;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
List<Point> points;
List<Point> shapePoints;
Matrix m;
float dx, dy;
public Form1()
{
InitializeComponent();
points = new List<Point>();
shapePoints = new List<Point>();
foreach (Control c in this.Controls)
{
points.Add(c.Location);
}
foreach (Shape s in this.shapeContainer1.Shapes)
{
if (s is SimpleShape)
{
shapePoints.Add((s as SimpleShape).Location);
}
else if (s is LineShape)
{
shapePoints.Add((s as LineShape).StartPoint);
}
}
m = new Matrix();
dx = this.Width;
dy = this.Height;
// this code will allow(?) do not move this control
this.shapeContainer1.Dock = DockStyle.Fill;
}
protected override void OnSizeChanged(EventArgs e)
{
dx = this.Width / dx;
dy = this.Height / dy;
ApplyScale(dx, dy);
dx = this.Width;
dy = this.Height;
base.OnSizeChanged(e);
}
private void ApplyScale(float dx, float dy)
{
//m.Reset();
m.Scale(dx, dy);
Point[] locations = points.ToArray();
m.TransformVectors(locations);
for (int i = 0; i < this.Controls.Count; i++)
{
this.Controls[i].Location = locations[i];
}
Point[] shapeLocations = shapePoints.ToArray();
m.TransformVectors(shapeLocations);
for (int i = 0; i < this.shapeContainer1.Shapes.Count; i++)
{
SimpleShape ss = this.shapeContainer1.Shapes.get_Item(i)
as SimpleShape;
if (ss != null)
{
ss.Location = locations[i];
continue;
}
LineShape ls = this.shapeContainer1.Shapes.get_Item(i)
as LineShape;
if (ls != null)
{
ls.StartPoint = locations[i];
ls.Scale(new SizeF(dx, dy));
}
}
}
}
}
这就是我得到的:
alt text http://lh4.ggpht.com/_1TPOP7DzY1E/TAOYg9fh5EI/AAAAAAAADOE/IPCdAFw-NFo/s800/Untitled-1.png
答案 0 :(得分:1)
这似乎有效: 在表单加载中,我为每个要调整大小的控件存储%-left和%-top。我将它存储在Tag-property中以便于访问。 然后在form-resize事件中,我只为每个控件计算新的%-left和%-top并将它们定位。
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
For Each c As Control In Me.Controls
c.Anchor = AnchorStyles.None
c.Tag = CInt((100 / Me.Width) * c.Left).ToString & "|" & CInt((100 / Me.Height) * c.Top).ToString
Next
End Sub
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
For Each c As Control In Me.Controls
c.Location = New Point((Me.Width / 100) * CInt(Split(c.Tag, "|")(0)), (Me.Height / 100) * CInt(Split(c.Tag, "|")(1)))
Next
End Sub
开始:
alt text http://img52.imageshack.us/img52/4918/33405487.jpg
表单调整大小后: alt text http://img190.imageshack.us/img190/4107/29607470.jpg
答案 1 :(得分:-1)
在表单上放置一个停靠(或锚定)表格布局面板,并将其所有列/行设置为百分比大小。
然后,您可以将控件停靠在单元格中,并且在调整表格布局时,单元格将保持比例。
修改强>
对于叠加元素,您是否可以不增加TLP中的列数/行数来容纳?
如果减少列数/行数,然后将子TLP添加到需要更多定位的单元格中?