Winforms自动滚动在控件调整大小时丢失

4
我有一个用户控件,用于显示客车的座位布局。
它简单地以矩阵方式绘制多个“SeatControl”,具体取决于乘客车大小。
为了更好地查看,主控件调整“SeatControl”以适应所有可用空间,这意味着根据可用空间,SeatControls会变得更大或更小。
这个完美的运作。
但是,当客户区域太小时,我们避免将控件缩小太多,否则它们会变形且难以阅读。
在这种情况下,我们打开自动滚动,使用户可以滚动查看整个布局。
但是,如果我们从小屏幕开始(带滚动条),将其最大化(滚动条将隐藏并且座位控件会增加大小),然后恢复窗口大小(滚动条将重新出现且座位控件将缩小到最小尺寸),则滚动将丢失。
为了清楚起见,请看以下图片中的相同操作: small layout with vertical scroll bar 最大化窗口(仅显示部分屏幕以避免大图像): partial full screen, notice that scroll has gone as expected 然后将其恢复(请注意滚动条和客户区域上的布局位置): but on scroll bar 此调整大小由以下代码控制:
private void FixSizes()
    {            
        if (mModel == null)
            return;

        this.SuspendLayout();            

        Size clientSize = this.ClientSize;
        Size minimumSize = new Size(SeatUserControl.MinimumDescentSize.Width, SeatUserControl.MinimumDescentSize.Height);

        //Here we try to find the best size for the seat user control to fit all the client area                      
        Size controlSize = new Size(
            Math.Max(clientSize.Width / mModel.Length, minimumSize.Width),
            Math.Max(clientSize.Height / mModel.Width, minimumSize.Height)
        );

        AutoScrollMinSize = new Size(controlSize.Width * mModel.Length, controlSize.Height * mModel.Width);
        this.SetDisplayRectLocation(0, 0);

        for (int row = 0; row < mModel.Width; ++row)
        {
            for (int col = 0; col < mModel.Length; ++col)
            {
                Control control = this.Controls[(row * mModel.Length) + col];

                control.Location = new Point(col * controlSize.Width, row * controlSize.Height);
                control.Size = controlSize;
            }
        }            

        this.ResumeLayout();
    }

这个方法仅仅被 OnClientSizeChanged 方法调用:

protected override void OnClientSizeChanged(EventArgs e)
    {
        base.OnClientSizeChanged(e);

        this.FixSizes();
    }

我发现如果将SeatControl保持固定大小,问题就会消失,但输出效果不好,因为我们希望SeatControl使用尽可能多的空间。

看起来我忘记或者未设置自动滚动选项,以免丢失信息。有什么想法吗?


你尝试过使用面板的 Dock 设置来拉伸布局吗?如果你正在使用座位布局的面板,这可能会有帮助。 - Siva Gopal
@SivaGopal:我没有这样做,SeatControls直接插入到了UserControl上。但如果我使用停靠,那么我会失去滚动条,对吗? - bcsanches
1
假设您正在使用某种父容器,例如面板或限制SeatControl最大尺寸的其他容器,请使用“Fill”(中心位置)停靠方式。这将自动调整滚动条以适应控件。 - KreepN
1
@KreepN,持有所有座位控件的用户控件很简单,只需将座位放在其上即可。我现在添加了一个新的面板,并将其停靠设置为“填充”,并用座位控件填充了该面板。看起来效果不错!谢谢! - bcsanches
将我的评论转化为了一个答案。作为以后的参考,使用TableLayoutPanel和SplitContainer(带有Dock Fill)可以帮助维护一个美观的应用程序。 - KreepN
1
@KreeN 我的第一个设计是使用TableLayout,但我无法使其在控件不断添加/删除和调整大小时正常工作。手动控制控件对于这种情况导致了更简单和出乎意料的快速代码。谢谢。 - bcsanches
1个回答

2

评论中的解决方案:

假设您正在使用某种父容器,例如面板或其他会限制SeatControl最大化大小的东西,请使用停靠“填充”(中心位置)。这将自动调整控件的滚动条。

对于未来的读者,在使用Dock:Fill属性时,结果如下所示:

enter image description here

请注意,由于GridView控件大于其父容器而自动生成的滚动条。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接