質問

I have a problem with a flowlayoutpanel in WinForms.

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. I wanted to show only the vertical scrollbar, so using the event ClientSizeChanged i modify the child controls width. 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:

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 (e.g. 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:

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帰属
所属していません StackOverflow
scroll top