Question

I have a little demonstration below of a peculiar problem.

using System;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public class TestForm : Form
    {
        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.TextBox textBox1;

        public TestForm()
        {
            //Controls
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.textBox1 = new System.Windows.Forms.TextBox();

            // tabControl1
            this.tabControl1.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.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Location = new System.Drawing.Point(12, 12);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(260, 240);
            this.tabControl1.TabIndex = 0;
            this.tabControl1.Selected += new System.Windows.Forms.TabControlEventHandler(this.tabControl1_Selected);

            // tabPage1
            this.tabPage1.Controls.Add(this.textBox1);
            this.tabPage1.Location = new System.Drawing.Point(4, 22);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Size = new System.Drawing.Size(252, 214);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = "tabPage1";

            // tabPage2
            this.tabPage2.Location = new System.Drawing.Point(4, 22);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Size = new System.Drawing.Size(192, 74);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = "tabPage2";

            // textBox1
            this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBox1.Location = new System.Drawing.Point(6, 38);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(240, 20);
            this.textBox1.TabIndex = 0;

            // TestForm
            this.ClientSize = new System.Drawing.Size(284, 264);
            this.Controls.Add(this.tabControl1);
            this.Name = "Form1";
            this.Text = "Form1";
        }

        //Tab Selected
        private void tabControl1_Selected(object sender, EventArgs e)
        {
            this.Text = "TextBox Width: " + this.textBox1.Width.ToString();
        }
    }

    //Main
    static class Program
    {
        static void Main()
        {
            Application.Run(new TestForm());
        }
    }

}

If you run the above C# code you will have a small form containing a tabcontrol. Within the tabcontrol is a texbox on the first tab. If you follow these steps you will see the problem:

  1. Select tabPage2 (textBox1's width is reported in the form title)
  2. Resize the form
  3. Select tabPage1 (The wrong textBox1 width is reported)

Any ideas what is going on here? The textbox is obviously bigger than what is being reported. If you click again on tabPage2 the correct size is then updated. Obviously there is an event updating the width of textBox1. Can i trigger this when tabPage1 is selected?

Was it helpful?

Solution

Firstly, thanks for the complete program - it made it much easier to work out what was going on!

While the textbox isn't visible, it isn't resized. When you select tabPage1, the Selected event fires before the controls become visible and the textbox gets laid out again.

Now, that's why it's happening - but what's your real situation? If you actually want to capture the size of controls changing, subscribe to their Resize events. If not, could you explain more about what you're trying to achieve?

OTHER TIPS

I'm pretty sure that what's happening is the Selected event is raised slightly before the tab page becomes visible. The text box is not resized until the tab page becomes visible, so you end up checking the value of the text box's size before it is actually resized. When you change tabs again, the text box is already resized, so you get the correct value.

Change the last few lines of your example form to look like this and it will become apparent:

            this.textBox1.SizeChanged += TextboxSizeChanged;
        }

        //Tab Selected
        private void tabControl1_Selected(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("tab selected");
            this.Text = "TextBox Width: " + this.textBox1.Width.ToString();
        }

        private void TextboxSizeChanged(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine("Textbox resized");
        }

If you modify your code a little by adding an event handler to the textbox1.Resize event you will see what happens. The tabPage1.Selected event occurs before the controls in the tab page is resized so when you check the width of the textbox you are checking it before it is resized.

Normally this wouldn't be a problem, for the resizing is done properly afterwards, but I guess that you will be using the size of the textbox for something?

You should be able to write your own TabControl that fixes this problem, but you will have to experiment to see what works here.

Not sure if I understand the problem. But, you might use textbox's resize event to capture the width change OR form's resize.

In your example, does the select event of tabPage1 fire when you do step 3?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top