繁体   English   中英

调整用户控件的大小-将控件锚定到表单中心

[英]Resizing User Control - anchor controls to center of form

我有一个用户控件,它由两个控件和四个按钮组成,排列在窗体上:两个控件在侧面,而按钮在垂直行中间。

在应用程序中使用控件时,我将其放在窗体上。

现在,在水平调整表单大小时,两个控件只是在向左或向右移动而不改变其大小。

我需要的是控件保持锚定在表单的中间并向侧面扩展(很抱歉,由于不够清晰,我准备了屏幕截图,但该网站不允许我附加它们)。

有没有一种方法可以在不覆盖Resize事件的情况下完成此任务?

使用TableLayoutPanel作为用户控件的基础。
您需要3列和1行。 中间一列需要具有固定的大小,其余两列则设置为50%。 不用担心,.Net足够聪明,可以计算出它们实际占用的百分比。
在左右两列中,放置控件,并将两者的Dock属性都设置为fill 在中间一列中,放置一个面板,并将其Dock属性设置为fill为墙,然后在该面板中,将按钮置于中间。
将表布局面板设置为Dock也要fill ,将用户控件添加到表单时,也要使用Dock topbottomfill

看来确实不能在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM