【问题标题】:Resizing User Control - anchor controls to center of form调整用户控件的大小 - 将控件锚定到表单中心
【发布时间】:2015-05-03 06:06:13
【问题描述】:

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

在应用程序中使用控件时,我将其放置在表单上。

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

我需要的是控件保持固定在表单的中间并增长到两侧(抱歉不够清晰,我准备了屏幕截图,但网站不允许我附加它们)。

有没有办法在不覆盖 Resize 事件的情况下完成此操作?

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

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

    【讨论】:

    • 致 OP,如果您需要更多有关表格布局的帮助,请查看此链接:msdn.microsoft.com/en-us/library/dd492143.aspx
    • @Zohar 谢谢,它工作得很好,除了:1:我希望两个侧栏独立调整大小(因为它们保持 50% 的纵横比),2:我想底部的两个按钮粘在底部(就像顶部的按钮粘在顶部)。能做到吗?
    • 你可以上传一些图片来准确显示你想要的行为并在 cmets 中留下一个链接吗?
    • 我想在我原来的问题中添加图片,但我被告知我的代表不够高:-(
    • 只需将它们上传到某个位置并给出链接...google.co.il/…
    【解决方案2】:

    勘误: 上面的代码大部分时间都可以工作,但是对于某些 Move-Resize 序列它会失败。解决方案是响应父窗体(控件的使用者)的移动和调整大小事件,而不是控件本身。 还有一件事:由于事件触发顺序(先移动后调整大小,必须将工作代码从 Resize() 移动到 Move(),这似乎违反直觉,但似乎是正确的方式。

    【讨论】:

    • 这不是答案,应该在您的问题中进行编辑。
    【解决方案3】:

    似乎确实无法在 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 事件,而不是控件本身。

    还有一件事:由于事件触发顺序(Move 首先是 Resize,必须将工作代码从 Resize() 移动到 Move(),这似乎违反直觉,但似乎是正确的方式。

    【讨论】:

    • 理想的 StackOverflow 由一个问题和 一个 答案组成。请学习使用编辑功能来改进您的帖子,而不是在一个帖子中发布多个回复。
    猜你喜欢
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    相关资源
    最近更新 更多