Quantcast
Viewing all articles
Browse latest Browse all 12583

How to get FlowLayoutPanel to re-WrapContents now, please?

FlowLayoutPanel's WrapContents behavior is mostly working well for us... whenever it wraps, it does the right thing. The problem is when it doesn't re-compute its wrapping... 

We have its FlowDirection set to TopDown with WrapContents true and AutoScroll true such that if all the fixed-width Controls that it contains have heights that are shorter than the FlowLayoutPanel's height, then we get N columns, no vertical scrollbar, but possibly a horizontal scrollbar (iff more columns than fit in the FlowLayoutPanel's width).  Perfect.

If you grow the height of a control in the FlowLayoutPanel such that it's taller than the FlowLayoutPanel, then that will be placed in a column by itself, and the FlowLayoutPanel will get a vertical scrollbar.  Good... that's what we want.

But that's the ONLY case where there should be a vertical scrollbar... when one of the child Controls is taller than the FlowLayoutPanel.  And that's usually the only case... but not entirely stable:

(1) If one of your Controls just fits without wrapping when there is no horizontal scrollbar, but would have wrapped if there was a horizontal scrollbar, then when that horizontal scrollbar gets added, the FlowLayoutPanel doesn't re-do the wrapping... it leaves that Control there, which then forces the vertical scrollbar to come on when the horizontal one does.  Which can be really irritating to our users.  How can we force it to re-wrap whenever the scrollbars come on?  Or how can we set it up to add the horizontal scrollbar outside itself?  Or how can we force the horizontal scrollbar to always be on?  Or???

(2) If you increase the height of a Control to be taller than the FlowLayoutPanel, forcing the FlowLayoutPanel to add a vertical scrollbar, and then simply shrink the height of that Control back down to where the vertical scrollbar should no longer be necessary, it won't re-wrap the other controls allowing the vertical scrollbar to go away.  How can we force a re-wrap?

To demo this, you can use the simple WinForms App project below:

(A)  Start the app... Click Add Box a dozen times or more... see how the wrapping works... just a horizontal scrollbar... that's the desired behavior.  Click Clear All.

(B)  Click Add Small until you get scrolling... notice you get BOTH horizontal and vertical scrollbars... that is NOT desired.  When it added the horizontal scrollbar, it should have re-wrapped the controls so that a vertical scroll bar is not needed.  Click Clear All.

(C)  Click Add Box a dozen times or more... all is working well.   On the second box in the first column, left click to increase its height.  Repeat that until the box is taller than the FlowLayoutPanel such that a vertical scrollbar appears. Now Shift-Click to reduce its size back... notice that the vertical scrollbar goes away.  Perfect.  Click the box again to grow it to force a vertical scroll bar to appear again.  And then click the box one more time to size it enough taller that the column next to it gets four of the normal sized boxes in it.  Now Shift-Click twice to reduce the box back to where no vertical scrollbar should be required... but notice the vertical scrollbar does NOT go away this time.  Arg.  The column with four boxes does not get re-wrapped back down.

Is there a way to tell the FlowLayoutPanel "rewrap your contents now, please"?

I tried by setting WrapContents = false and then setting WrapContents = true.  But setting it true doesn't cause it to re-wrap... it just causes anything added later to wrap.  You can see this in the app below by:

(D)  Click the Re-Wrap button.  You end up with one column... because setting WrapContents = false forced it to one column.  But then setting WrapContents = true does NOT cause it to re-compute the wrapping.  If you then AddBox, you'll see it wraps to the next column.  Ugh.

Suggestions?

// Form1.Designer.cs

namespace FlowLayoutPanelTester
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.AddTextBox = new System.Windows.Forms.Button();
            this.AddSmallBox = new System.Windows.Forms.Button();
            this.ReWrap = new System.Windows.Forms.Button();
            this.button4 = new System.Windows.Forms.Button();
            this.button5 = new System.Windows.Forms.Button();
            this.button6 = new System.Windows.Forms.Button();
            this.ClearAll = new System.Windows.Forms.Button();
            this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
            this.SuspendLayout();
            // 
            // AddTextBox
            // 
            this.AddTextBox.Location = new System.Drawing.Point(13, 13);
            this.AddTextBox.Name = "AddTextBox";
            this.AddTextBox.Size = new System.Drawing.Size(75, 23);
            this.AddTextBox.TabIndex = 0;
            this.AddTextBox.Text = "Add Box";
            this.AddTextBox.UseVisualStyleBackColor = true;
            this.AddTextBox.Click += new System.EventHandler(this.AddTextBox_Click);
            // 
            // AddSmallBox
            // 
            this.AddSmallBox.Location = new System.Drawing.Point(94, 13);
            this.AddSmallBox.Name = "AddSmallBox";
            this.AddSmallBox.Size = new System.Drawing.Size(75, 23);
            this.AddSmallBox.TabIndex = 1;
            this.AddSmallBox.Text = "Add Small";
            this.AddSmallBox.UseVisualStyleBackColor = true;
            this.AddSmallBox.Click += new System.EventHandler(this.AddSmallBox_Click);
            // 
            // ReWrap
            // 
            this.ReWrap.Location = new System.Drawing.Point(175, 13);
            this.ReWrap.Name = "ReWrap";
            this.ReWrap.Size = new System.Drawing.Size(75, 23);
            this.ReWrap.TabIndex = 2;
            this.ReWrap.Text = "Re-Wrap";
            this.ReWrap.UseVisualStyleBackColor = true;
            this.ReWrap.Click += new System.EventHandler(this.ReWrap_Click);
            // 
            // button4
            // 
            this.button4.Location = new System.Drawing.Point(259, 13);
            this.button4.Name = "button4";
            this.button4.Size = new System.Drawing.Size(75, 23);
            this.button4.TabIndex = 3;
            this.button4.Text = "button4";
            this.button4.UseVisualStyleBackColor = true;
            // 
            // button5
            // 
            this.button5.Location = new System.Drawing.Point(340, 13);
            this.button5.Name = "button5";
            this.button5.Size = new System.Drawing.Size(75, 23);
            this.button5.TabIndex = 4;
            this.button5.Text = "button5";
            this.button5.UseVisualStyleBackColor = true;
            // 
            // button6
            // 
            this.button6.Location = new System.Drawing.Point(421, 13);
            this.button6.Name = "button6";
            this.button6.Size = new System.Drawing.Size(75, 23);
            this.button6.TabIndex = 5;
            this.button6.Text = "button6";
            this.button6.UseVisualStyleBackColor = true;
            // 
            // ClearAll
            // 
            this.ClearAll.Location = new System.Drawing.Point(503, 12);
            this.ClearAll.Name = "ClearAll";
            this.ClearAll.Size = new System.Drawing.Size(75, 23);
            this.ClearAll.TabIndex = 6;
            this.ClearAll.Text = "Clear All";
            this.ClearAll.UseVisualStyleBackColor = true;
            this.ClearAll.Click += new System.EventHandler(this.ClearAll_Click);
            // 
            // flowLayoutPanel1
            // 
            this.flowLayoutPanel1.AutoScroll = true;
            this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
            this.flowLayoutPanel1.Location = new System.Drawing.Point(13, 43);
            this.flowLayoutPanel1.Name = "flowLayoutPanel1";
            this.flowLayoutPanel1.Size = new System.Drawing.Size(565, 417);
            this.flowLayoutPanel1.TabIndex = 7;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(593, 472);
            this.Controls.Add(this.flowLayoutPanel1);
            this.Controls.Add(this.ClearAll);
            this.Controls.Add(this.button6);
            this.Controls.Add(this.button5);
            this.Controls.Add(this.button4);
            this.Controls.Add(this.ReWrap);
            this.Controls.Add(this.AddSmallBox);
            this.Controls.Add(this.AddTextBox);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button AddTextBox;
        private System.Windows.Forms.Button AddSmallBox;
        private System.Windows.Forms.Button ReWrap;
        private System.Windows.Forms.Button button4;
        private System.Windows.Forms.Button button5;
        private System.Windows.Forms.Button button6;
        private System.Windows.Forms.Button ClearAll;
        private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
    }
}


// Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace FlowLayoutPanelTester
{
    public partial class Form1 : Form
    {
        private const string testText 
                         = "This is a test of a little TextBox.  "+ "This is only a test.  Had this been "+ "an actual TextBox, you would have been "+ "informed of something potentially useful.  "+ "Instead, this TextBox is babbling randomly "+ "for the sole purpose of avoiding having to "+ "type some pointless text over and over.  "+ "I put this into code form just once, "+ "and then each time a push the button, I get "+ "a TextBox that already contains plenty of "+ "Text to have some size, and plenty that I "+ "can simply copy and paste if I need a really "+ "long block.  This is only a test.";


        public Form1()
        {
            InitializeComponent();
        }


        private void TextBox_Click(object sender, EventArgs e)
        {
            TextBox textBox = sender as TextBox;
            if (textBox != null)
            {
                if (Control.ModifierKeys != Keys.Shift)
                    textBox.Height += 100;
                else
                {
                    if (textBox.Height >= 120)
                        textBox.Height -= 100;
                    else
                        textBox.Height = 20;
                }
            }
        }


        private void AddTextBox_Click(object sender, EventArgs e)
        {
            TextBox textBox = new TextBox();
            textBox.BorderStyle = BorderStyle.FixedSingle;
            textBox.WordWrap = true;
            textBox.Multiline = true;
            textBox.Width = 200;
            textBox.Height = 100;
            this.flowLayoutPanel1.Controls.Add(textBox);

            textBox.Click += new EventHandler(this.TextBox_Click);
        }


        private void AddSmallBox_Click(object sender, EventArgs e)
        {
            TextBox textBox = new TextBox();
            textBox.BorderStyle = BorderStyle.FixedSingle;
            textBox.WordWrap = true;
            textBox.Multiline = true;
            textBox.Width = 200;
            textBox.Height = 20;
            this.flowLayoutPanel1.Controls.Add(textBox);

            textBox.Click += new EventHandler(this.TextBox_Click);
        }


        private void ClearAll_Click(object sender, EventArgs e)
        {
            this.flowLayoutPanel1.Controls.Clear();
        }


        private void ReWrap_Click(object sender, EventArgs e)
        {
            this.flowLayoutPanel1.WrapContents = false;
            this.flowLayoutPanel1.WrapContents = true;
        }

    }
}



Viewing all articles
Browse latest Browse all 12583

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>