关于TabControl中事件特性的问题

时间:2021-06-02 23:59:34

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:

如果你运行上面的C#代码,你将有一个包含tabcontrol的小表单。在tabcontrol中是第一个选项卡上的texbox。如果您按照这些步骤操作,您将看到问题:

  1. Select tabPage2 (textBox1's width is reported in the form title)
  2. 选择tabPage2(textBox1的宽度在表单标题中报告)

  3. Resize the form
  4. 调整表单大小

  5. Select tabPage1 (The wrong textBox1 width is reported)
  6. 选择tabPage1(报告错误的textBox1宽度)

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?

有什么想法在这里发生了什么?文本框明显大于报告的内容。如果再次单击tabPage2,则会更新正确的大小。显然有一个事件更新textBox1的宽度。选择tabPage1时可以触发这个吗?

4 个解决方案

#1


2  

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.

虽然文本框不可见,但未调整大小。当您选择tabPage1时,在控件变为可见之前触发Selected事件,并再次布置文本框。

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?

现在,这就是它发生的原因 - 但你的真实情况是什么?如果您确实要捕获更改控件的大小,请订阅其Resize事件。如果没有,你能解释一下你想要实现的目标吗?

#2


1  

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.

我很确定发生的事情是在标签页变为可见之前稍微提出了Selected事件。在标签页变为可见之前,文本框不会调整大小,因此您最终会在实际调整大小之前检查文本框大小的值。再次更改选项卡时,文本框已调整大小,因此您可以获得正确的值。

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");
        }

#3


1  

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.

如果通过向textbox1.Resize事件添加事件处理程序来稍微修改代码,您将看到会发生什么。 tabPage1.Selected事件发生在选项卡页面中的控件调整大小之前,因此当您检查文本框的宽度时,您将在调整它之前调整它的大小。

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.

您应该能够编写自己的TabControl来修复此问题,但您必须尝试查看此处的作用。

#4


-1  

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

不确定我是否理解这个问题。但是,您可以使用文本框的resize事件来捕获宽度更改或窗体的大小调整。

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

在您的示例中,当您执行第3步时,tabPage1的select事件是否会触发?

#1


2  

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.

虽然文本框不可见,但未调整大小。当您选择tabPage1时,在控件变为可见之前触发Selected事件,并再次布置文本框。

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?

现在,这就是它发生的原因 - 但你的真实情况是什么?如果您确实要捕获更改控件的大小,请订阅其Resize事件。如果没有,你能解释一下你想要实现的目标吗?

#2


1  

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.

我很确定发生的事情是在标签页变为可见之前稍微提出了Selected事件。在标签页变为可见之前,文本框不会调整大小,因此您最终会在实际调整大小之前检查文本框大小的值。再次更改选项卡时,文本框已调整大小,因此您可以获得正确的值。

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");
        }

#3


1  

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.

如果通过向textbox1.Resize事件添加事件处理程序来稍微修改代码,您将看到会发生什么。 tabPage1.Selected事件发生在选项卡页面中的控件调整大小之前,因此当您检查文本框的宽度时,您将在调整它之前调整它的大小。

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.

您应该能够编写自己的TabControl来修复此问题,但您必须尝试查看此处的作用。

#4


-1  

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

不确定我是否理解这个问题。但是,您可以使用文本框的resize事件来捕获宽度更改或窗体的大小调整。

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

在您的示例中,当您执行第3步时,tabPage1的select事件是否会触发?