简体   繁体   English

C#FlowLayoutPanel和控件的自动大小

[英]C# FlowLayoutPanel and autosize of controls

I have a problem with a flowlayoutpanel in WinForms. 我在WinForms中遇到flowlayoutpanel的问题。

What I'm trying to do is a sort of chat program; 我想做的是一种聊天程序; every message is handled by a custom usercontrol. 每条消息均由自定义用户控件处理。 Anyway the same behaviour is with any control, so I'll use a button in this question just to be more clear. 无论如何,任何控件都具有相同的行为,因此我将在这个问题中使用一个按钮以使其更加清楚。

To show the controls I tried using a flowlayoutpanel. 为了显示控件,我尝试使用flowlayoutpanel。 I wanted to show only the vertical scrollbar, so using the event ClientSizeChanged i modify the child controls width. 我只想显示垂直滚动条,因此我使用事件ClientSizeChanged修改了子控件的宽度。 Here is the panel configuration: 这是面板配置:

this.flw_chat.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
        | System.Windows.Forms.AnchorStyles.Left) 
        | System.Windows.Forms.AnchorStyles.Right)));
this.flw_chat.AutoScroll = true;
this.flw_chat.AutoScrollMinSize = new System.Drawing.Size(100, 0);
this.flw_chat.BackColor = System.Drawing.Color.LightGray;
this.flw_chat.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.flw_chat.Location = new System.Drawing.Point(12, 27);
this.flw_chat.Name = "flw_chat";
this.flw_chat.Size = new System.Drawing.Size(439, 320);
this.flw_chat.TabIndex = 4;
this.flw_chat.ClientSizeChanged += new System.EventHandler(this.flw_chat_ClientSizeChanged);

and here is the ClientSizeChanged event: 这是ClientSizeChanged事件:

private void flw_chat_ClientSizeChanged(object sender, EventArgs e)
{
    if (CurrentFlowWidthWidth != flw_chat.ClientRectangle.Width)
    CurrentFlowWidthWidth = flw_chat.ClientRectangle.Width;
    foreach (Control c in flw_chat.Controls)
    {
        c.Width = CurrentFlowWidthWidth - c.Margin.Horizontal;
    }
}

while this is the code to add a control (eg button) 这是添加控件的代码(例如按钮)

var temp = new Button();
temp.Text = "AAA";
if (CurrentFlowWidthWidth != flw_chat.ClientRectangle.Width)
    flw_chat_ClientSizeChanged(null, null);
temp.Width = CurrentFlowWidthWidth - temp.Margin.Horizontal;
flw_chat.Controls.Add(temp);

Now, the behaviour is a little strange. 现在,该行为有些奇怪。 In my opinion the controls should occupy every pixel of the panel; 我认为控件应占据面板的每个像素。 when the vertical scrollbar is displayed all the controls have to resize to the new dimension, while when the panel is resized the controls have to follow it. 当显示垂直滚动条时,所有控件都必须调整为新尺寸,而在调整面板大小时,控件必须跟随新尺寸。

This is the behaviour I normally see. 这是我通常看到的行为。 BUT there are two exceptions: 但是有两个例外:

  • Sometimes when I resize the control quickly the horizontal scrollbar is shown; 有时,当我快速调整控件的大小时,会显示水平滚动条。 if I stop when the scrollbar is shown then it remains on screen until I resize it again (it looks like the panel keeps in memory the old size and displays the scrollbar according to this old size) 如果在显示滚动条时我停了下来,那么它会一直停留在屏幕上,直到我再次调整其大小为止(看起来面板会在内存中保留旧尺寸,并根据此旧尺寸显示滚动条)
  • When the vertical scrollbar appears, also the horizontal one is shown, even if the controls inside are drawn in the correct size. 当出现垂直滚动条时,即使内部控件以正确的大小绘制,也会显示水平滚动条。 When i add another control or I resize the scrollbar disappears; 当我添加另一个控件或调整大小时,滚动条消失; it looks like the scrollbar is shown before I edit the controls, but when I edit the controls the view is not updated and so the scrollbar "thinks" that the controls have the old width. 它看起来像在我编辑控件之前显示了滚动条,但是当我编辑控件时,视图没有更新,因此滚动条“认为”控件具有旧的宽度。

Do you know why it behaves this way? 您知道为什么会这样吗? How would you solve this? 您将如何解决?

I could not make the horizontal scrollbar go away completely, but with this code I was able to almost fix both of the problems you identified. 我无法完全消除水平滚动条,但是使用此代码,我几乎可以解决您发现的两个问题。 When resizing quickly, the horizontal scrollbar flickers, but it doesn't remain on the screen. 快速调整大小时,水平滚动条会闪烁,但不会保留在屏幕上。 And when the vertical scrollbar appears, it does another layout to remove the horizontal scrollbar. 并且当垂直滚动条出现时,它会进行另一种布局以删除水平滚动条。

Here is my revised ClientSizeChanged event handler: 这是我修改后的ClientSizeChanged事件处理程序:

private void flw_chat_ClientSizeChanged(object sender, EventArgs e)
{
    if (CurrentFlowWidthWidth != flw_chat.ClientSize.Width || flw_chat.HorizontalScroll.Visible)
    {
        CurrentFlowWidthWidth = flw_chat.ClientSize.Width;
        foreach (Control c in flw_chat.Controls)
            c.Width = CurrentFlowWidthWidth - c.Margin.Horizontal - 4;
    }
}

And here is my revised code to add a new control: 这是我修改后的代码以添加新控件:

private void AddControl_Click(object sender, EventArgs e)
{
    var temp = new Button();
    temp.Text = "AAA";
    if (CurrentFlowWidthWidth != flw_chat.ClientSize.Width)
        flw_chat_ClientSizeChanged(null, null);
    temp.Width = CurrentFlowWidthWidth - temp.Margin.Horizontal - 4;
    flw_chat.Controls.Add(temp);
    if (flw_chat.HorizontalScroll.Visible)
        flw_chat.PerformLayout();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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