[英]Resizing User Control - anchor controls to center of form
我有一个用户控件,它由两个控件和四个按钮组成,排列在窗体上:两个控件在侧面,而按钮在垂直行中间。
在应用程序中使用控件时,我将其放在窗体上。
现在,在水平调整表单大小时,两个控件只是在向左或向右移动而不改变其大小。
我需要的是控件保持锚定在表单的中间并向侧面扩展(很抱歉,由于不够清晰,我准备了屏幕截图,但该网站不允许我附加它们)。
有没有一种方法可以在不覆盖Resize事件的情况下完成此任务?
使用TableLayoutPanel
作为用户控件的基础。
您需要3列和1行。 中间一列需要具有固定的大小,其余两列则设置为50%。 不用担心,.Net足够聪明,可以计算出它们实际占用的百分比。
在左右两列中,放置控件,并将两者的Dock
属性都设置为fill
。 在中间一列中,放置一个面板,并将其Dock
属性设置为fill
为墙,然后在该面板中,将按钮置于中间。
将表布局面板设置为Dock
也要fill
,将用户控件添加到表单时,也要使用Dock
top
, bottom
或fill
。
看来确实不能在Designer中完成,但是这里是使用替代的解决方案。 它工作正常,除了一些我无法克服的控件闪烁。
public partial class SB : UserControl
{
//variables to remember sizes and locations
Size parentSize = new Size(0,0);
Point parentLocation = new Point (0,0);
......
// we care only for horizontal changes by dragging the left border;
// all others take care of themselves by Designer code
public void SB_Resize(object sender, EventArgs e)
{
if (this.Parent == null)
return;//we are still in the load process
// get former values
int fcsw = this.parentSize.Width;//former width
int fclx = this.parentLocation.X;//former location
Control control = (Control)sender;//this is our custom control
// get present values
int csw = control.Parent.Size.Width;//present width
int clx = control.Parent.Location.X;//present location
// both parent width and parent location have changed: it means we
// dragged the left border or one of the left corners
if (csw != fcsw && clx != fclx)
{
int delta = clx - fclx;
int lw = (int)this.tableLayoutPanel1.ColumnStyles[0].Width;
int nlw = lw - delta;
if (nlw > 0)
{
this.tableLayoutPanel1.ColumnStyles[0].Width -= delta;
}
}
this.parentSize = control.Parent.Size;//always update it
this.parentLocation = control.Parent.Location;
}
//contrary to documentation, the Resize event is not raised by moving
//the form, so we have to override the Move event too, to update the
//saved location
private void SB_Move(object sender, EventArgs e)
{
if (this.Parent == null)
return;//we are still in the load process
this.parentSize = this.Parent.Size;//always update it
this.parentLocation = this.Parent.Location;
}
}
上面的代码大多数时候都有效,但是对于某些Move-Resize序列却无效。 解决方案是响应父窗体(控件的使用者)而不是控件本身的Move和Resize事件。
还有一件事:由于事件触发顺序(先移动,然后移动Resize,必须将工作代码从Resize()移到Move(),这似乎违反直觉,但似乎仍是正确的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.